Что такое разреженный файл (sparse file)? |
![]() |
Добавил(а) microsin |
На физическом диске содержимое файла хранится блоками фиксированного размера (на современных файловых системах это блоки размером 4 KiB или больше). Когда все байты в таком блоке содержат 0, файловая система, в которой реализованы разреженные файлы (sparse files) не сохраняет такой блок на диск, записывая вместо этого информацию о таком блоке в метаданных файла. Достоинства использования разреженных файлов: • Пустые блоки данных не занимают место на диске; вместо этого в метаданных файла сохраняется только их идентификаторы (что составляет только несколько байт). Таким способом экономится 4 KiB (или больше) физического пространства диска на каждый пустой блок. Предположим, у все есть файл, где много пустых байт \x00. Эти пустые байты называют дырками (holes). Их хранение неэффективно, и мы знаем, сколько их в файле, так что зачем их хранить на устройстве? Вместо этого можно хранить метаданные, описывающие эти нули. Когда процесс считывает файл, эти блоки с нулевыми байтами генерируются динамически вместо того, чтобы считываться с физического устройства хранения (см. на следующую схему из Википедии): По этой причине применение разреженного файла эффективно, так как мы не сохраняем нули на диск, храня только небольшую порцию данных, описывающую сколько должно быть сгенерировано нулевых байт. Замечание: логический размер файла больше, чем физический размер разреженного файла. [fallocate: демонстрация разреженного файла] Если вы запустите команду: $ dd if=/dev/zero of=output bs=1G count=4 Эта команда копирует 4G блока нулевых байт в файл output. Чтобы это увидеть, запустите: $ stat output File: output Size: 4294967296 Blocks: 8388616 IO Block: 4096 regular file ... Вы увидите что для этого файла было выделено 8388616 блоков, в которых нет ничего, кроме пустых байт, которые были скопированы с устройства /dev/zero, и они действительно появились на физическом пространстве диске, это "дыры" (sparse zeros). Утилита dd сделала то, что вы запросили, скопировав блоки данных из одно файла в другой. Теперь запустите эту команду, чтобы определить дыры и сделать по месту разреженный файл: $ fallocate -d output $ stat output File: swapfile Size: 4294967296 Blocks: 0 IO Block: 4096 regular file ... Количество блоков теперь стало 0, потому блоки, где хранились только нули, были перераспределены. Поскольку блоки файла output ничего не хранят, только нули, команда fallocate -d определила эти пустоты и отменила выделение для них физического пространства. При этом размер файла не поменялся. Это логический (виртуальный размер) файла, но не его занимаемое место на диске. Помните, что когда вы читаете файл output, пустые байты генерируются файловой системой во время выполнения динамически, они на самом деле физически не хранятся на диске, и размер файла, как сообщает stat, является логическим размером, а физический размер равен нулю. В этом случае файловая система должна генерировать 4G пустых байтов, когда процесс читает файл. Для генерации разреженного файла с помощью dd: $ dd if=/dev/zero of=output2 bs=1G seek=0 count=0 $ stat stat output2 File: output2 Size: 4294967296 Blocks: 0 IO Block: 4096 regular file GNU dd внутри себя использует lseek и ftruncate, см. truncate(2) и lseek(2). [Ссылки] 1. What is a sparse file and why do we need it? site:stackoverflow.com. |