Что такое разреженный файл и зачем он нам нужен? Единственное, что я могу получить, это то, что это очень большой файл и он эффективен (в гигабайтах). Насколько это эффективно?
Что такое разреженный файл и зачем он нам нужен?
Ответы (2)
Скажем, у вас есть файл с большим количеством пустых байтов \x00
. Эти многочисленные пустые байты \x00
называются дырами. Хранение пустых байтов просто неэффективно, мы знаем, что их много в файле, так зачем хранить их на устройстве хранения? Вместо этого мы могли бы хранить метаданные, описывающие эти нули. Когда процесс читает файл, эти блоки с нулевым байтом генерируются динамически, а не сохраняются в физической памяти (посмотрите на эту схему из Википедии):
Вот почему разреженный файл эффективен, потому что он не хранит нули на диске, вместо этого он содержит достаточно данных, описывающих нули, которые будут сгенерированы.
Примечание. размер логического файла больше, чем размер физического файла для разреженных файлов. Это потому, что мы не сохранили нули физически на запоминающем устройстве.
Изменить:
Когда вы бежите:
$ dd if=/dev/zero of=output bs=1G count=4
Здесь команда копирует 4G-блоки нулевых байтов в output
. Чтобы увидеть это:
$ stat output
File: ouput
Size: 4294967296 Blocks: 8388616 IO Block: 4096 regular file
--omitted--
Вы можете видеть, что этому файлу выделено 8388616 блоков, эти блоки не хранят ничего, кроме пустых байтов, скопированных из /dev/zero
, и они действительно занимают место на физическом диске, в них хранятся дыры на диске (разреженные нули). dd
сделал то, что вы просили, скопировав блоки данных из одного файла в другой.
Теперь запустите эту команду, чтобы обнаружить дыры и сделать файл разреженным на месте:
$ fallocate -d output
$ stat output
File: swapfile
Size: 4294967296 Blocks: 0 IO Block: 4096 regular file
--omitted--
Вы что-то замечаете? Количество блоков теперь равно 0, потому что блоки, которые хранили только пустые байты, были освобождены. Помните, что блоки output
ничего не хранят, только кучу пустых нулей, fallocate -d
обнаружил блоки, содержащие только пустые нули, и освободил их, так как все блоки для этого файла содержат нули, все они были освобождены.
Также обратите внимание, что размер остался прежним. Это логический (виртуальный) размер файла, а не его размер на диске. Крайне важно знать, что output
теперь не занимает физическое пространство для хранения, ему выделено 0 блоков, и поэтому я действительно не использую дисковое пространство. Размер сохраняется после запуска fallocate -d
, поэтому, когда вы позже читаете файл, вы получаете пустые байты, сгенерированные для вас файловой системой во время выполнения. Однако физический размер output
равен нулю, не использует блоки данных.
Помните, что когда вы читаете output
файл, пустые байты генерируются файловой системой динамически во время выполнения, они не реально физически хранятся на диске, а размер файла, указанный stat
, является логическим размером, и физический размер равен нулю для output
. В этом случае файловая система должна генерировать 4 ГБ пустых байтов, когда процесс читает файл.
Чтобы сгенерировать разреженный файл с помощью 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).
sudo dd if=/dev/zero of=/swapfile bs=1G count=4
, этот файл будет иметь нулевой размер на диске? Правильно ?
- person Luv33preet; 05.09.2017
sudo dd if=/dev/zero of=/swapfile bs=1G count=4
, он не будет иметь нулевого размера на диске. Потому что dd
копирует нулевые байты в ваш файл. Другими словами, вы фактически скопировали нулевые байты из /dev/zero
в /swapfile
. Однако эта команда dd if=/dev/zero of=sparse_file bs=1G seek=4 count=0
создает разреженный файл, вы можете запустить stat
для обоих файлов и посмотреть, как изменится поле Blocks
. Ваша команда является рекомендуемым способом создания файла подкачки.
- person direprobs; 05.09.2017
fallocate -d /swapfile
, эта команда создаст файл подкачки на месте, удалив все блоки данных с нулевыми байтами, выделенные для /swapfile
. Опять же, вы можете проверить с помощью stat /swapfile
после выполнения команды fallocate
, посмотреть, что произойдет с количеством выделенных блоков. Однако не делайте этого с файлом подкачки, сделайте тест на другом файле.
- person direprobs; 05.09.2017
Разреженный файл — это файл, который в основном пуст, т. е. содержит большие блоки байтов, значение которых равно 0
(ноль).
На диске содержимое файла хранится блоками фиксированного размера (обычно 4 КиБ и более). Когда все байты, содержащиеся в таком блоке, равны 0
, файловая система, реализующая разреженные файлы, не сохраняет блок на диске, а хранит информацию где-то в метаданных файла.
Преимущества использования разреженных файлов:
- пустые блоки данных не занимают места на диске; они не хранятся как обычные блоки данных, их идентификаторы (использующие всего несколько байтов) хранятся вместо этого в метаданных файла; таким образом, для каждого пустого блока сохраняется 4 КиБ дискового пространства (или больше);
- чтение пустого блока данных из разреженного файла не требует времени; это происходит потому, что данные с диска не считываются; поскольку файловая система знает, что все байты в блоке равны
0
, она просто устанавливает в0
все байты во входном буфере, и данные готовы; нет необходимости обращаться к медленному накопителю; - запись пустого блока данных в разреженный файл не требует времени; при записи файловая система определяет, что блок пустой (все его байты равны
0
) и помещает идентификатор блока в список пустых блоков (в метаданные файла); данные на диск не записываются.
Дополнительную информацию о разреженных файлах можно найти на странице Википедии.