Можно ли сделать файл, который изначально был разреженным, а затем расширенным, снова?


29

Я знаю, что копирование или передача того, что изначально было разреженным файлом, без использования утилиты, которая понимает разреженные файлы, приведет к заполнению «дыр». Есть ли способ или утилита, чтобы превратить то, что когда-то было редким файлом, обратно в разреженное?

Например:
создать разреженный файл:

% dd if=/dev/zero of=TEST bs=1 count=0 seek=1G
# do some op that pads out the holes
% scp TEST localhost:~/TEST2
% ls -lhs TEST*
   0 -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:35 TEST
1.1G -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:37 TEST2

Есть ли способ:

% resparse TEST2
to get:
   0 -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:35 TEST
  0G -rw-rw-r--. 1 tony tony 1.0G Oct 16 13:37 TEST2

Извините, мне пришлось нарядить оригинальный квест ...
user25849

1
Единственное, что может сделать это из всего, что я видел, это GNU 'cp', как в '% cp --sparse = всегда ранее-sparse-файле вновь-sparse-файле' Хулитель, он этого не сделает ' на месте'.
user25849

Если вы хотите скопировать разреженный файл и позволить копированию быть разреженным, используйте rsync -aS.
Жиль "ТАК - перестань быть злым"

Ответы:


30

Редактировать 2015

начиная с util-linux 2.25, fallocateутилита для Linux имеет параметр -d/ --dig-holeдля этого.

fallocate -d the-file

Выкопал бы дыру для каждого блока, полного нулей в файле


В старых системах вы можете сделать это вручную:

У Linux есть FALLOC_FL_PUNCH_HOLEопция, fallocateкоторая может это сделать. Я нашел скрипт на github с примером:

Использование FALLOC_FL_PUNCH_HOLE из Python

Я немного изменил его, чтобы сделать то, что вы просили - пробивать дыры в областях файлов, заполненных нулями. Вот:

Использование FALLOC_FL_PUNCH_HOLE из Python для пробивания дырок в файлах

usage: punch.py [-h] [-v VERBOSE] FILE [FILE ...]

Punch out the empty areas in a file, making it sparse

positional arguments:
  FILE                  file(s) to modify in-place

optional arguments:
  -h, --help            show this help message and exit
  -v VERBOSE, --verbose VERBOSE
                        be verbose

Пример:

# create a file with some data, a hole, and some more data
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=0
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=2

# see that it has holes
$ du --block-size=1 --apparent-size test1
12288   test1
$ du --block-size=1 test1
8192    test1

# copy it, ignoring the hole
$ cat test1 > test2
$ du --block-size=1 --apparent-size test2
12288   test2
$ du --block-size=1 test2
12288    test2

# punch holes again
$ ./punch.py test2
$ du --block-size=1 --apparent-size test2
12288   test2
$ du --block-size=1 test2
8192    test2

# verify
$ cmp test1 test2 && echo "files are the same"
files are the same

Обратите внимание, что punch.pyдля поиска могут быть найдены только блоки по 4096 байт, поэтому он может сделать файл не таким редким, каким был при запуске. Конечно, это можно сделать умнее. Кроме того, это только слегка проверено , поэтому будьте осторожны и делайте резервные копии, прежде чем доверять ему!


1
Мне нравится это лучше всего, потому что это не требует переписывать весь файл снова.
Питер

8

Если вы хотите сделать файл разреженным, вы можете сделать это напрямую с помощью dd.

dd if=./zeropadded.iso of=./isnowsparse.iso conv=sparse

Из dd(1)руководства:

          sparse   If one or more output blocks would consist solely of
                   NUL bytes, try to seek the output file by the required
                   space instead of filling them with NULs, resulting in a
                   sparse file.

Итак, обратите внимание, что он будет искать вперед, только если весь блок пуст. Для максимальной редкости используйте bs=1.


2
Любой размер блока меньше, чем на bs=512самом деле не имеет смысла, так как диски являются блочными устройствами. ( bs=4096В более новых дисков)
Лапо

Похоже, это эквивалентноcp --sparse=always zeropadded.iso isnowsparse.iso
maxschlepzig

2

Если не tarсчитать его с -Sфлагом (при условии GNU tar), и повторно выполнить scp... нет. Никакая полезность, о которой я знаю, не могла бы знать, где были «дыры».


5
GNU cp будет анализировать файл: со страницы man: укажите --sparse = всегда, чтобы создать разреженный файл DEST, когда файл SOURCE содержит достаточно длинную последовательность нулевых байтов.
user25849

Потрясающе. Узнайте что-нибудь каждый день - когда этот флаг был введен? Платит, чтобы читать man-страницы "известных" программ время от времени; D
tink

2

Мне повезло с этим:

cd whatever
rsync -avxWSHAXI . .

В -Iсилах RSync обновить все файлы, независимо от того, считает ли он , что они изменили или нет; -Sвызывает новые файлы , которые будут sparsified. -aделает это рекурсивно, так что вы можете разделить целые деревья каталогов одной командой.

Это не так хорошо, как специальный инструмент, который выслеживает дыры и уничтожает их FALLOC_FL_PUNCH_HOLE, но это лучше, чем дублирование целых деревьев каталогов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.