В информатике разреженный файл — это тип компьютерного файла , который пытается использовать пространство файловой системы более эффективно, когда сам файл частично пуст. Это достигается путем записи краткой информации ( метаданных ) , представляющей пустые блоки, на носитель данных вместо фактического «пустого» пространства, составляющего блок, таким образом, потребляя меньше места для хранения. Полный блок записывается на носитель как фактический размер только тогда, когда блок содержит «реальные» (непустые) данные.
Чаще всего разреженные файлы создаются, когда блоки файла никогда не записываются. Это типично для файлов с произвольным доступом, таких как базы данных. Некоторые операционные системы или утилиты идут дальше, «разреживая» файлы при их записи или копировании: если блок содержит только нулевые байты, он не записывается в хранилище, а помечается как пустой.
При чтении разреженных файлов файловая система прозрачно преобразует метаданные, представляющие пустые блоки, в «реальные» блоки, заполненные нулевыми байтами во время выполнения. Приложение не знает об этом преобразовании.
Большинство современных файловых систем поддерживают разреженные файлы, включая большинство вариантов Unix и NTFS . [1] HFS+ от Apple не обеспечивает поддержку разреженных файлов, но в OS X уровень виртуальной файловой системы поддерживает их хранение в любой поддерживаемой файловой системе, включая HFS+. [ необходима ссылка ] Файловая система Apple (APFS) также поддерживает их. [2] Разреженные файлы обычно используются для образов дисков , снимков баз данных , файлов журналов и в научных приложениях.
Преимущество разреженных файлов в том, что дисковое пространство выделяется только тогда, когда оно действительно необходимо: емкость хранилища сохраняется, и большие файлы иногда могут быть созданы, даже если на носителе недостаточно свободного места для исходного файла. Это также сокращает время первой записи, поскольку системе не нужно выделять блоки для «пропущенного» пространства. Если первоначальное выделение требует записи всех нулей в пространство, это также избавляет систему от необходимости дважды записывать «пропущенное» пространство.
Например, образ виртуальной машины с максимальным размером 100 ГБ, в котором фактически записано 2 ГБ файлов, потребует полных 100 ГБ при резервировании предварительно выделенным хранилищем, но только 2 ГБ в разреженном файле. Если файловая система поддерживает перфорацию и гостевая операционная система выдает команды TRIM , удаление файлов на гостевой системе соответственно уменьшит необходимое пространство.
Недостатки в том, что разреженные файлы могут стать фрагментированными ; отчеты о свободном пространстве файловой системы могут быть обманчивыми; заполнение файловых систем, содержащих разреженные файлы, может иметь неожиданные эффекты (например, ошибки переполнения диска или превышения квоты при простой перезаписи существующей части файла, который оказался разреженным); а копирование разреженного файла с помощью программы , которая явно их не поддерживает, может скопировать весь несжатый размер файла, включая нулевые разделы, которые не выделены на носителе, — теряя преимущества свойства разреженности в файле. Разреженные файлы также не полностью поддерживаются всеми программами или приложениями резервного копирования. Однако реализация VFS обходит [ требуется цитата ] предыдущие два недостатка. Загрузка исполняемых файлов в 32-битной Windows (exe или dll), которые являются разреженными, занимает гораздо больше времени, поскольку файл не может быть отображен в памяти в ограниченном адресном пространстве 4 ГБ, и не кэшируется, поскольку отсутствует codepath для кэширования 32-битных разреженных исполняемых файлов (Windows на 64-битных архитектурах может отображать разреженные исполняемые файлы). [ необходима цитата ] В NTFS разреженные файлы (или, скорее, их ненулевые области) не могут быть сжаты. NTFS реализует разреженность как особый вид сжатия, поэтому файл может быть либо разреженным, либо сжатым.
Разреженные файлы обычно обрабатываются прозрачно для пользователя. Но различия между обычным файлом и разреженным файлом становятся очевидными в некоторых ситуациях.
Команда Unix
dd из = разреженный файл bs = 5M seek = 1 count = 0
создаст файл размером пять мебибайт , но без каких-либо данных, сохраненных на носителе (только метаданные ). ( GNU dd
имеет такое поведение, поскольку он вызывает ftruncate
установку размера файла; другие реализации могут просто создать пустой файл.)
Аналогично можно использовать команду truncate, если она доступна:
truncate -s 5M <имя_файла>
В Linux существующий файл можно преобразовать в разреженный следующим образом:
fallocate -d <имя_файла>
Не существует переносимого системного вызова для проделывания дыр; Linux предоставляет fallocate(FALLOC_FL_PUNCH_HOLE)
, а Solaris предоставляет fcntl(F_FREESP)
.
Опция -s
команды ls
показывает занятое пространство в блоках.
ls -ls разреженный-файл
В качестве альтернативы du
команда печатает занятое пространство, в то время как ls
печатает видимый размер. В некоторых нестандартных версиях du
опция --block-size=1
печатает занятое пространство в байтах вместо блоков, так что его можно сравнить с ls
выводом:
du --block-size = 1 разреженный файлls -l разреженный-файл
Обратите внимание, что приведенное выше использование du имеет сокращенный формат синтаксиса опций «du -B 1 sf», что само по себе эквивалентно самой короткой версии «du -b sf», как указано в руководстве du: [3] -b, --bytes
эквивалентно --apparent-size --block-size=1
.
Кроме того, инструмент filefrag
из e2fsprogs
пакета можно использовать для отображения сведений о распределении блоков файла.
filefrag -v разреженный-файл
Обычно версия GNU cp
хорошо определяет, является ли файл разреженным, поэтому
cp разреженный-файл новый-файл
создает новый файл, который будет разреженным. Однако GNU cp имеет опцию --sparse
. [4] Это особенно полезно, если файл, содержащий длинные нулевые блоки, сохраняется неразреженным способом (т.е. нулевые блоки были записаны на носитель полностью). Место для хранения можно сэкономить, выполнив:
cp --sparse=всегда файл1 файл1_sparsed
Некоторые реализации cp, например cp FreeBSD , не поддерживают эту --sparse
опцию и всегда расширяют разреженные файлы. Частично жизнеспособной альтернативой в этих системах является использование rsync с собственной --sparse
опцией [5] вместо cp. К сожалению, --sparse
нельзя объединить с --inplace
. [6] [7] Более новые версии rsync поддерживают --sparse
объединение с --inplace
. [8]
Через стандартный ввод разреженное копирование файлов достигается следующим образом:
cp --sparse = всегда /dev/fd/0 новый-разреженный-файл < некоторый-файл