Как программно создать разреженный файл в C на Mac OS X? - PullRequest
8 голосов
/ 09 октября 2008

Я хотел бы создать разреженный файл, чтобы блоки с нулем не занимали фактического дискового пространства, пока я не запишу в них данные. Возможно ли это?

Ответы [ 7 ]

11 голосов
/ 11 октября 2008

Кажется, существует некоторая путаница относительно того, поддерживает ли файловая система Mac OS X по умолчанию (HFS +) дыры в файлах. Следующая программа демонстрирует, что это не так.

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

void create_file_with_hole(void)
{
    int fd = open("file.hole", O_WRONLY|O_TRUNC|O_CREAT, 0600);
    write(fd, "Hello", 5);
    lseek(fd, 99988, SEEK_CUR); // Make a hole
    write(fd, "Goodbye", 7);
    close(fd);
}

void create_file_without_hole(void)
{
    int fd = open("file.nohole", O_WRONLY|O_TRUNC|O_CREAT, 0600);
    write(fd, "Hello", 5);
    char buf[99988];
    memset(buf, 'a', 99988);
    write(fd, buf, 99988); // Write lots of bytes
    write(fd, "Goodbye", 7);
    close(fd);
}

int main()
{
    create_file_with_hole();
    create_file_without_hole();
    return 0;
}

Программа создает два файла, каждый длиной 100 000 байт, один из которых имеет отверстие 99 988 байт.

В Mac OS X 10.5 в разделе HFS + оба файла занимают одинаковое количество дисковых блоков (200):

$ ls -ls
total 400
200 -rw-------  1 user  staff  100000 Oct 10 13:48 file.hole
200 -rw-------  1 user  staff  100000 Oct 10 13:48 file.nohole

В то время как в CentOS 5 файл без дырок потребляет на 88 блоков больше, чем другие:

$ ls -ls
total 136
 24 -rw-------  1 user   nobody 100000 Oct 10 13:46 file.hole
112 -rw-------  1 user   nobody 100000 Oct 10 13:46 file.nohole
7 голосов
/ 09 октября 2008

Как и в других Unix, это особенность файловой системы. Либо файловая система поддерживает его для ВСЕХ файлов, либо нет. В отличие от Win32, вам не нужно делать ничего особенного, чтобы это произошло. Кроме того, в отличие от Win32, использование разреженного файла не снижает производительность.

В MacOS файловой системой по умолчанию является HFS +, которая не поддерживает разреженные файлы.

Обновление: MacOS, используемый для поддержки томов UFS с разреженной поддержкой файлов, но он был удален. Ни одна из поддерживаемых в настоящее время файловых систем не поддерживает разреженные файлы.

2 голосов
/ 23 июня 2010

Эта тема становится исчерпывающим источником информации о разреженных файлах. Вот недостающая часть для Win32:

Достойный товар с примерами

Инструмент, который оценивает, имеет ли смысл делать файл разреженным

Привет

1 голос
/ 09 октября 2008

hdiutil может обрабатывать редкие изображения и файлы, но, к сожалению, фреймворк, на который он ссылается, является приватным.

Вы можете попытаться определить внешние символы, как это определено в нижеприведенной платформе DiskImages, но, скорее всего, это неприемлемо для производственного кода, к тому же, поскольку среда является частной, вам придется пересмотреть варианты ее использования.

cristi: ~ diciu $ otool -L / usr / bin / hdiutil

/ USR / бен / hdiutil: /System/Library/PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages (совместимость версия 1.0.8, текущая версия 194.0.0) [..]

cristi: ~ diciu $ nm /System/Library/PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages | awk -F '' '{print $ 3}' | с ++ фильт | grep -i разреженный

[..]

CSparseFile :: sector2Band (long long)

CSparseFile :: addIndexNode ()

CSparseFile :: readIndexNode (long long, SparseFileIndexNode *)

CSparseFile :: readHeaderNode (CBackingStore *, SparseFileHeaderNode *, без знака long)

[... вырезано для краткости]

Позже Редактировать

Вы можете использовать hdiutil в качестве внешнего процесса и создать для него разреженный образ диска. Из процесса C вы затем создадите файл в (смонтированном) разреженном образе диска.

0 голосов
/ 29 декабря 2013

Похоже, OS X поддерживает разреженные файлы на томах UDF. Я попробовал тестовую программу Titaniumdecoy на OS X 10.9, и она сгенерировала разреженный файл на образе диска UDF. Кроме того, UFS больше не поддерживается в OS X, поэтому, если вам нужны разреженные файлы, UDF - единственная изначально поддерживаемая файловая система, которая их поддерживает.

Я также попробовал программу на акциях SMB. Когда сервером является Ubuntu (файловая система ext4), программа создает разреженный файл, но 'ls -ls' через SMB этого не показывает. Если вы выполните команду «ls -ls» на самом хосте Ubuntu, это покажет, что файл редкий. Если на сервере установлена ​​Windows XP (файловая система NTFS), программа не создает разреженный файл.

0 голосов
/ 11 октября 2008

Если вы стремитесь (fseek, ftruncate, ...) к концу, размер файла будет увеличиваться без выделения блоков, пока вы не напишите в дыры. Но нет способа создать волшебный файл, который автоматически преобразует блоки с нулями в дыры. Ты должен сделать это сам.

Это может быть полезно посмотреть (команда OpenBSD cp вставляет отверстия вместо записи нулей). патч

0 голосов
/ 09 октября 2008

Если вам нужна мобильность, в крайнем случае вы должны написать свою собственную функцию доступа, чтобы вы могли управлять индексом и набором блоков.

По сути, вы управляете одним файлом, поскольку ОС управляет диском, сохраняя цепочку блоков, являющихся частью файла, растровое изображение выделенных / свободных блоков и т. Д.

Конечно, это приведет к неоптимизированному и более медленному доступу, я рекомендую эту аппроксимацию, только если требование экономии места является абсолютно критическим, и у вас есть достаточно времени, чтобы написать надежный набор функций доступа.

И даже в этом случае я бы сначала выяснил, нуждается ли ваша проблема в другом решении. Возможно, вы должны хранить ваши данные по-другому?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...