Можно ли выделить файловые дыры для другого файла?

При первом запуске приложения (или ином чтении с диска в память) данные с диска кэшируются в свободную оперативную память (называемую «буферами» в вывод бесплатно). Если одни и те же данные необходимо прочитать последовательно, прежде чем кеш будет удален или использован для других данных, они считываются из ОЗУ, что, естественно, быстрее, чем чтение с диска. Единственный разумный способ ускорить время первого запуска — приобрести более быстрый носитель данных.

0
25.08.2017, 21:27
1 ответ

Прежде всего, что такое дыра в файле? Это просто данные, установленные на ноль, без явной записи как таковой. Когда вы ищете1639 байт после конца вашего файла и записываете в него 100 байт, ваш файл фактически увеличивается на 1639+100 байт. Итак, вы создали дыру, но на самом деле эта дыра заполнена нулями.

Если эта дыра достаточно велика, некоторые файловые системы (например, ext) позволяют сэкономить это пространство, не выделяя соответствующие блоки на диске. т.е. если ваш seekсобирается записать один или несколько блоков нулей, блоки не размещаются на диске, и это создаст настоящие дыры в списке блоков, содержащих данные файла. Это то, что мы называемразреженным файлом.

Размер блока зависит от формата вашей файловой системы. В настоящее время с extэто обычно 4096 байт. Это означает, что при поиске по 1639 байт вы не создаете разреженный файл, и 1639 нулей будут просто записаны на диск. OTOH, с блоками по 4096 байт, если вы ищете как минимум 8191 (2 * 4096 - 1) байт, вы можете быть уверены, что создадите хотя бы один.

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

На самом деле, лучшая демонстрация не требует программы на C:

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda4        38G   28G  7.5G  80% /

$ time dd of=/tmp/foo bs=1M seek=$((1024*1024*10)) count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 4.741e-05 s, 0.0 kB/s

real    0m0.002s
user    0m0.000s
sys 0m0.000s

$ ls -lh /tmp/foo
-rw-r--r-- 1 xhienne xhienne 10T Aug 25 20:08 /tmp/foo

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda4        38G   28G  7.5G  80% /

Здесь я создал файл размером 10 ТБ (полный нулей) за пару миллисекунд на разделе, имеющем всего 7+ ГБ свободного места (что до сих пор доступен).

3
28.01.2020, 02:24

Теги

Похожие вопросы