Как сделать файл разреженным?
Если у меня есть большой файл, содержащий много нулей, как я могу эффективно сделать его разреженным?
Является ли единственной возможностью прочитать весь файл (включая все нули, которые могут быть сохранены непостоянно) и переписать его в новый файл, используя поиск, чтобы пропустить нулевые области?
Или есть возможность сделать это в существующем файле (например, File.setSparse (длинный старт, длинный конец))?
Я ищу решение в Java или в некоторых командах Linux, файловая система будет ext3 или аналогичной.
4 ответа
Некоторые файловые системы в Linux / UNIX имеют возможность "пробивать дыры" в существующем файле. Увидеть:
- LKML публикует информацию об этой функции
- FAQ по обрезанию файлов в UNIX (поиск по F_FREESP)
Это не очень портативно и не сделано так же по всем направлениям; на данный момент, я полагаю, что библиотеки ввода-вывода Java не предоставляют интерфейс для этого.
Если перфорация доступна либо через fcntl(F_FREESP)
или через любой другой механизм, он должен быть значительно быстрее, чем цикл копирования / поиска.
За 8 лет многое изменилось.
fallocate -d
filename
может использоваться для пробивания отверстий в существующих файлах. От fallocate(1)
справочная страница:
-d, --dig-holes
Detect and dig holes. This makes the file sparse in-place,
without using extra disk space. The minimum size of the hole
depends on filesystem I/O block size (usually 4096 bytes).
Also, when using this option, --keep-size is implied. If no
range is specified by --offset and --length, then the entire
file is analyzed for holes.
You can think of this option as doing a "cp --sparse" and then
renaming the destination file to the original, without the
need for extra disk space.
See --punch-hole for a list of supported filesystems.
(Этот список:)
Supported for XFS (since Linux 2.6.38), ext4 (since Linux
3.0), Btrfs (since Linux 3.7) and tmpfs (since Linux 3.5).
Я думаю, что было бы лучше предварительно выделить весь файл и поддерживать таблицу /BitSet страниц / разделов, которые заняты.
Создание разреженного файла приведет к фрагментации этих разделов, если они когда-либо будут использоваться повторно. Возможно, сохранение нескольких ТБ дискового пространства не стоит потери производительности сильно фрагментированного файла.
Ты можешь использовать $ truncate -s filename filesize
на Linux Teminal для создания разреженного файла, имеющего
только метаданные.
ПРИМЕЧАНИЕ. - Размер файла указан в байтах.
Согласно этой статье, кажется, что в настоящее время нет простого решения, кроме использования FIEMAP ioctl. Тем не менее, я не знаю, как вы можете превратить "неразреженные" нулевые блоки в "разреженные".