可以将原来稀疏然后扩展的文件再次设为稀疏文件吗?


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

抱歉,我不得不
修饰

1
从我所看到的所有内容中唯一可以做到这一点的是GNU'cp',例如'%cp --sparse = always以前是稀疏文件,新稀疏文件'贬低者是不会这样做'到位'。
user25849 '10 -10-16

如果要复制稀疏文件并使副本稀疏,请使用rsync -aS
吉尔(Gilles)'所以

Answers:


30

编辑2015

从util-linux 2.25开始,fallocateLinux上的实用程序具有-d/ --dig-hole选项。

fallocate -d the-file

将挖掘每满的块中的孔文件中


在较旧的系统上,您可以手动执行此操作:

Linux有一个FALLOC_FL_PUNCH_HOLE选项fallocate可以做到这一点。我在github上找到了一个带有示例的脚本:

从Python使用FALLOC_FL_PUNCH_HOLE

我对其进行了一些修改,以执行您要求的操作-在填充零的文件区域打孔。这里是:

从Python使用FALLOC_FL_PUNCH_HOLE在文件中打孔

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在较新的驱动器中)
lapo

看起来等效于cp --sparse=always zeropadded.iso isnowsparse.iso
maxschlepzig

2

tar用-ing它-S标志(假设的GNU tar),并重新执行scp...没有。我知道的任何实用程序都无法知道“漏洞”的位置。


5
GNU cp将重新解析文件:从手册页:每当SOURCE文件包含足够长的零字节序列时,指定--sparse = always始终创建一个稀疏DEST文件。
user25849 2012年

太棒了 每天学习一些东西-何时引入该标志?有时需要付费阅读“著名”程序的手册页; D
2012年

2

我很幸运:

cd whatever
rsync -avxWSHAXI . .

-I部队rsync将更新所有文件,无论其是否认为他们已经改变与否; 将-S导致新的文件被sparsified。-a使其递归发生,因此您可以在一个命令中稀疏整个目录树。

它不如使用定制工具来寻找漏洞并使用销毁它们FALLOC_FL_PUNCH_HOLE,但是它比必须复制整个目录树要好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.