使用标准工具(例如 gzip、bzip2、xz)将一堆文件压缩在一起可以改善压缩吗?
我一直认为情况确实如此,但从未测试过。如果我们将同一个 20Mb 文件的 2 个副本随机字节压缩在一起,那么一个聪明的压缩程序就可以意识到这一点,将整个 tarball 压缩到近 20Mb。
我刚刚尝试使用 gzip、bzip2 和 xz 来压缩 1) 随机字节的文件,2) 该文件的两个副本的 tarball,以及 3) 该文件的两个副本的 cat。在所有情况下,压缩都不会减小文件大小。对于情况 1,这是预期的结果,但对于情况 2 和 3,最佳结果是 40Mb 文件可以缩小到接近 20Mb。对于压缩程序来说,这是一个很难看到的洞察力,特别是因为冗余很远,所以我不会期望一个完美的结果,但我仍然认为会有一些压缩。
测试:
dd if=/dev/urandom of=random1.txt bs=1M count=20
cp random1.txt random2.txt
cat random1.txt random2.txt > random_cat.txt
tar -cf randoms.tar random1.txt random2.txt
gzip -k random* &
bzip2 -k random* &
xz -k random* &
wait
du -sh random*
结果:
20+0 records in
20+0 records out
20971520 bytes (21 MB) copied, 1.40937 s, 14.9 MB/s
[1] Done gzip -k random*
[2]- Done bzip2 -k random*
[3]+ Done xz -k random*
20M random1.txt
21M random1.txt.bz2
21M random1.txt.gz
21M random1.txt.xz
20M random2.txt
21M random2.txt.bz2
21M random2.txt.gz
21M random2.txt.xz
40M random_cat.txt
41M random_cat.txt.bz2
41M random_cat.txt.gz
41M random_cat.txt.xz
41M randoms.tar
41M randoms.tar.bz2
41M randoms.tar.gz
41M randoms.tar.xz
这通常是我应该期待的吗?
有没有办法提高压缩率?
答案1
您面临着压缩器的“块大小”。大多数压缩程序将输入分成块并压缩每个块。看来 bzip 块大小最多只能达到 900K,因此它不会看到任何需要超过 900K 字节来重复的模式。
http://www.bzip.org/1.0.3/html/memory-management.html
gzip 似乎使用 32K 块。
有了xz,你就很幸运了!从手册页:
Preset DictSize CompCPU CompMem DecMem
-0 256 KiB 0 3 MiB 1 MiB
-1 1 MiB 1 9 MiB 2 MiB
-2 2 MiB 2 17 MiB 3 MiB
-3 4 MiB 3 32 MiB 5 MiB
-4 4 MiB 4 48 MiB 5 MiB
-5 8 MiB 5 94 MiB 9 MiB
-6 8 MiB 6 94 MiB 9 MiB
-7 16 MiB 6 186 MiB 17 MiB
-8 32 MiB 6 370 MiB 33 MiB
-9 64 MiB 6 674 MiB 65 MiB
因此“xz -8”将找到最多 32MB 的模式,而“xz -9”最多可找到 64MB 的模式。但要注意执行压缩(和解压缩)需要多少内存......
答案2
正如已经指出的:
- 使用随机文件不好,因为它们已经包含最大的“信息熵”,因此不会压缩;
- 你需要打包很多文件进行公平比较。
更好的测试用例可能是这样的:
cd /var/tmp
tar -zcf test1.tar /usr
tar -cf test2.tar /usr
gzip test2.tar
ls -h
(注:希望下面没有坐骑/usr
!)
您可以tar -jcf
改为使用 xz 压缩。
现在如果test2.tar.gz
小于test1.tar.gz,则测试成功(即先压缩文件再压缩比先压缩再压缩更好)。我的猜测是,对于很多(即数千个)文件来说。缺点是它可能需要更长的时间来执行,并且需要更多的磁盘空间,因为它必须先构建整个 tar 文件,然后对其进行压缩。这就是为什么经常使用第一种方法的原因,因为它会动态压缩每个文件,即使它可能不会提供那么小的 tarball。
例如,在异地备份中,我们通常会备份 4,000,000 个文件,总计约 2TB。因此第一种方法要快得多,并且不需要额外的 2TB 磁盘。
答案3
这随机的您选择的文件内容不是一个好例子 - 压缩的 tar 文件将是大比原来的。对于已经压缩格式的文件(例如,许多图像/音频/视频格式),您会看到相同的情况。
但是,将具有可压缩内容的多个文件打包在一起通常会比单独打包它们时产生更小的总 tar 文件大小,特别是当内容相似时(例如来自同一程序的日志文件)。原因是某些每个文件的压缩偏移数据(例如某些压缩算法的模式数组)可以由同一 tarfile 中的所有文件共享。