Как сделать файл разреженным?

Если у меня есть большой файл, содержащий много нулей, как я могу эффективно сделать его разреженным?

Является ли единственной возможностью прочитать весь файл (включая все нули, которые могут быть сохранены непостоянно) и переписать его в новый файл, используя поиск, чтобы пропустить нулевые области?

Или есть возможность сделать это в существующем файле (например, File.setSparse (длинный старт, длинный конец))?

Я ищу решение в Java или в некоторых командах Linux, файловая система будет ext3 или аналогичной.

4 ответа

Решение

Некоторые файловые системы в Linux / UNIX имеют возможность "пробивать дыры" в существующем файле. Увидеть:

Это не очень портативно и не сделано так же по всем направлениям; на данный момент, я полагаю, что библиотеки ввода-вывода Java не предоставляют интерфейс для этого.

Если перфорация доступна либо через fcntl(F_FREESP) или через любой другой механизм, он должен быть значительно быстрее, чем цикл копирования / поиска.

За 8 лет многое изменилось.

fallocate -dfilename может использоваться для пробивания отверстий в существующих файлах. От 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. Тем не менее, я не знаю, как вы можете превратить "неразреженные" нулевые блоки в "разреженные".

Другие вопросы по тегам