Spa*_*sle 12 tar archive compression gzip
.tar.gz
档案的一个问题是,当我尝试只列出档案的内容时,计算机实际上会对其进行解压缩,如果文件很大,这将需要很长时间。
其他文件格式,如.7z
, .rar
,.zip
没有这个问题。列出它们的内容只需一瞬间。
在我天真的看来,这是.tar.gz
存档格式的一个巨大缺点。
所以我实际上有两个问题:
.tar.gz
尽管有这个缺点,为什么人们使用这么多? Sté*_*las 21
重要的是要了解这里有一个权衡。
tar
表示磁带存档器。在磁带上,您主要进行顺序读取和写入。磁带现在很少使用,但tar
仍被使用,因为它能够以流的形式读取和写入数据。
你可以做:
tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'
Run Code Online (Sandbox Code Playgroud)
你不能这样做zip
。
如果不zip
先将存档内容存储在本地可查找文件中,您甚至无法列出存档内容。像:
curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin
Run Code Online (Sandbox Code Playgroud)
不会工作。
为了实现内容的快速阅读,zip
或者类似需要建立一个索引。该索引可以存储在文件的开头(在这种情况下,它只能写入常规文件,不能写入流),也可以存储在末尾,这意味着存档器需要在最后打印之前记住所有存档成员并且意味着截断的存档可能无法恢复。
这也意味着存档成员需要单独压缩,这意味着压缩率要低得多,尤其是在有很多小文件的情况下。
格式的另一个缺点zip
是存档与压缩相关联,您无法选择压缩算法。了解tar
过去如何使用compress
( tar.Z
)压缩档案,然后使用gzip
,然后bzip2
,然后xz
设计出性能更高的新压缩算法。加密也是如此。现在谁会相信zip
加密?
现在,tar.gz
档案的问题不在于您需要解压缩它们。解压缩通常比读取磁盘更快(您可能会发现列出大型 tgz 存档的内容比列出未缓存在内存中时未压缩的相同内容更快),但是您需要读取整个存档。
无法快速读取索引并不是真正的问题。如果您确实预见需要经常读取档案的表格内容,则可以将该列表存储在单独的文件中。例如,在创建时,您可以执行以下操作:
tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz
Run Code Online (Sandbox Code Playgroud)
IMO 的一个更大的问题是,由于存档的顺序方面,您无法在不阅读导致它的存档的整个开头部分的情况下提取单个文件。IOW,您不能在存档中进行随机读取。
现在,对于可查找的文件,它不必是那样的。
如果您使用 压缩您的tar
档案gzip
,将其作为一个整体进行压缩,则压缩算法使用在开始时看到的数据进行压缩,因此您必须从头开始解压缩。
但是xz
可以将格式配置为在单独的单独块中压缩数据(足够大以便压缩有效),这意味着只要您在这些压缩块的末尾保留索引,对于可查找文件,您就可以访问随机解压缩数据(至少以块为单位)。
pixz
(parallel xz
) 在压缩tar
档案时使用该功能,还在xz
文件末尾添加档案的每个成员的开始索引。
因此,对于可查找的文件,如果它们已被压缩,您不仅可以立即获得 tar 存档的内容列表(尽管没有元数据)pixz
:
pixz -l file.tar.xz
Run Code Online (Sandbox Code Playgroud)
但是您也可以提取单个元素而无需阅读整个档案:
pixz -x archive/member.txt < file.tar.xz | tar xpf -
Run Code Online (Sandbox Code Playgroud)
现在,至于为什么像7z
或zip
很少在 Unix 上使用的东西主要是因为它们无法归档 Unix 文件。它们是为其他操作系统设计的。您无法使用这些来忠实地备份数据。它们无法存储所有者(id 和名称)、权限等元数据,它们无法存储符号链接、设备、fifo...,它们无法存储有关硬链接的信息以及其他元数据信息,如扩展属性或 ACL。
其中一些甚至不能存储具有任意名称的成员(有些会因反斜杠或换行符或冒号或非 ascii 文件名而窒息)(tar
尽管某些格式也有限制)。
如果不明显,则不使用 atgz
或tar.bz2
, tar.xz
... 存档为:
unxz 文件.tar.xz tar tvf 文件.tar xz文件.tar
如果您.tar
的文件系统上有一个未压缩的文件,那说明您做错了什么。
那些整点xz
/ bzip2
/gzip
是流的压缩机是,它们可以在运行中所使用的,在管道中
unxz < file.tar.xz | tar tvf -
Run Code Online (Sandbox Code Playgroud)
虽然现代tar
的实现知道如何调用unxz
/ gunzip
/bzip2
本身,所以:
tar tvf file.tar.xz
Run Code Online (Sandbox Code Playgroud)
通常也可以工作(并且再次动态解压缩数据,而不是将存档的未压缩版本存储在磁盘上)。
这是一个用各种格式压缩的 Linux 内核源代码树。
$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.zip
97038336 linux-4.6.7z
89468928 linux-4.6.tar.xz
Run Code Online (Sandbox Code Playgroud)
首先,如上所述,7z 和 zip 略有不同,因为它们无法在其中存储少数符号链接并且缺少大部分元数据。
现在有几个时间在刷新系统缓存后列出内容:
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null 0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null 8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.zip > /dev/null
unzip -v linux-4.6.zip > /dev/null 0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null 0.51s user 0.15s system 89% cpu 0.739 total
Run Code Online (Sandbox Code Playgroud)
您会注意到,即使在这台 7 年前的 PC 上列出tar.xz
文件也比列出文件更快,.tar
因为从磁盘读取这些额外的兆字节比读取和解压缩较小的文件需要更长的时间。
那么好的,用 7z 或 zip 列出档案会更快,但这不是问题,正如我所说,通过将文件列表与档案一起存储很容易解决:
$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null 0.05s user 0.00s system 99% cpu 0.051 total
Run Code Online (Sandbox Code Playgroud)
即使在删除缓存后,甚至比 7z 或 zip 还要快。您还会注意到存档及其索引的累积大小仍然小于 zip 或 7z 存档。
或者使用pixz
索引格式:
$ xzcat linux-4.6.tar.xz | pixz -9 > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null 0.04s user 0.01s system 57% cpu 0.087 total
Run Code Online (Sandbox Code Playgroud)
现在,要提取存档的各个元素,tar 存档的最坏情况是访问最后一个元素时:
$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root 5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c 7.27s user 1.13s system 115% cpu 7.279 total
wc 0.00s user 0.00s system 0% cpu 7.279 total
Run Code Online (Sandbox Code Playgroud)
这很糟糕,因为它需要读取(和解压缩)整个存档。与之比较:
$ time unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c 0.02s user 0.01s system 19% cpu 0.119 total
wc 0.00s user 0.00s system 1% cpu 0.119 total
Run Code Online (Sandbox Code Playgroud)
我的7z版本好像不能随机访问,所以好像比tar.xz
:
$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
257 638 5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null 7.28s user 0.12s system 89% cpu 8.300 total
wc 0.00s user 0.00s system 0% cpu 8.299 total
Run Code Online (Sandbox Code Playgroud)
现在因为我们有我们之前pixz
生成的:
$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz 1.37s user 0.06s system 84% cpu 1.687 total
tar xOf - 0.00s user 0.01s system 0% cpu 1.693 total
wc 0.00s user 0.00s system 0% cpu 1.688 total
Run Code Online (Sandbox Code Playgroud)
它更快但仍然相对较慢,因为存档包含几个大块:
$ pixz -tl linux-4.6.tar.pixz
17648865 / 134217728
15407945 / 134217728
18275381 / 134217728
19674475 / 134217728
18493914 / 129333248
336945 / 2958887
Run Code Online (Sandbox Code Playgroud)
所以pixz
仍然需要读取和解压缩一个(最多一个)~19MB 的大块数据。
我们可以通过使档案成为更小的块(并牺牲一些磁盘空间)来使随机访问更快:
$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2 0.17s user 0.02s system 98% cpu 0.189 total
tar xOf - 0.00s user 0.00s system 1% cpu 0.188 total
wc 0.00s user 0.00s system 0% cpu 0.187 total
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5606 次 |
最近记录: |