立即打印存档文件列表(无需解压缩整个存档)


10

.tar.gz存档的问题在于,当我尝试仅列出存档内容时,计算机实际上将其解压缩,如果文件很大,这将花费很长时间。

其他文件格式,如.7z.rar.zip没有这个问题。列出它们的内容仅需一瞬间。

在我看来,这是.tar.gz存档格式的巨大缺点。

所以我实际上有两个问题:

  1. .tar.gz尽管有这个缺点,为什么人们仍然使用这么多?
  2. 如果我想要“即时内容列表”功能,我有哪些选择(我的意思是其他软件或工具)?


先用Gunzip压缩一下?
杰夫·谢勒

Answers:


18

重要的是要了解这里需要权衡。

tar表示磁带存档器。在磁带上,您通常执行顺序读取和写入。磁带如今很少使用,但tar仍以其以流形式读取和写入数据的能力而被使用。

你可以做:

tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'

您无法使用zip或类似功能执行此操作。

如果不zip先将档案内容本地存储在可搜索的文件中,就无法列出档案内容。像这样:

curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin

将无法正常工作。

为了实现对内容等的快速阅读,zip需要建立索引。该索引可以存储在文件的开头(在这种情况下,它只能写入常规文件,不能写入流),也可以存储在结尾,这意味着存档者需要记住所有存档成员,然后才能将其打印到末尾。并表示已截断的存档可能无法恢复。

这也意味着存档成员需要单独压缩,这意味着压缩率要低得多,尤其是在有很多小文件的情况下。

诸如此类的格式的另一个缺点zip是存档与压缩链接在一起,您无法选择压缩算法。查看tar以前如何使用compresstar.Z),然后使用gzip,然后使用,然后bzip2xz使用新的性能更高的压缩算法来压缩档案。加密也是如此。zip如今,谁会信任加密?

现在,tar.gz存档的问题不是解压缩它们所需要的那么多。解压缩通常比读取磁盘要快(您可能会发现,列出大型tgz归档文件的内容要比未缓存在内存中的未压缩文件的列出要快),但是您需要读取整个归档文件。

无法快速读取索引并不是真正的问题。如果确实需要经常读取存档的表内容,则可以将该列表存储在单独的文件中。例如,在创建时,您可以执行以下操作:

tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz

IMO的一个更大问题是,由于存档的顺序性,您无法在不读取导致存档的整个存档开始部分的情况下提取单个文件。IOW,您不能在存档中进行随机读取。

现在,对于可搜索的文件,不必一定是这种方式。

如果使用压缩tar档案gzip,将其整体压缩,则压缩算法将使用开始时看到的数据进行压缩,因此必须从头开始进行解压缩。

但是,xz可以将格式配置为将数据压缩为单独的单个块(足够大以使压缩高效),这意味着,只要在这些压缩块的末尾保留索引,对于可搜索的文件,您就可以访问随机解压缩数据(至少成块)。

pixz(parallel xz)在压缩tar档案时使用该功能,还可以在xz文件末尾添加档案每个成员的开头索引。

因此,对于可搜索的文件,如果使用压缩文件,则不仅可以立即获得tar存档内容的列表(尽管没有元数据)pixz

pixz -l file.tar.xz

但是您也可以提取单个元素,而不必阅读整个档案:

pixz -x archive/member.txt < file.tar.xz | tar xpf -

现在,关于为什么类似7zzip很少在Unix上使用的东西主要是因为它们无法归档Unix文件。它们是为其他操作系统设计的。您无法使用这些数据进行忠实的数据备份。他们不能存储所有者(ID和名称),权限等元数据,不能存储符号链接,设备,FIFO等...,也不能存储有关硬链接的信息以及其他扩展属性或ACL之类的元数据信息。

其中一些甚至不能存储具有任意名称的成员(某些成员会因反斜杠或换行符或冒号或非ascii文件名而阻塞)(tar尽管某些格式也有局限性)。

切勿将tgz / tar.xz文件解压缩到磁盘上!

如果不太明显,则不要使用tgztar.bz2tar.xz...存档,例如:

unxz file.tar.xz
tar tvf file.tar
xz file.tar

如果您.tar的文件系统上有未压缩的文件,则说明您做错了什么。

那些整点xz/ bzip2/ gzip是流的压缩机是,它们可以在运行中所使用的,在管道中

unxz < file.tar.xz | tar tvf -

虽然现代tar的实现知道如何调用unxz/ gunzip/ bzip2本身,所以:

tar tvf file.tar.xz

通常也会起作用(并再次动态解压缩数据,并且不将存档的未压缩版本存储在磁盘上)。

这是用各种格式压缩的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

首先,如上所述,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

您会注意到列出tar.xz文件的速度比使用.tar这台7年历史的PC还要快,因为从磁盘读取这些额外的兆​​字节要比读取和解压缩较小的文件花费的时间更长。

然后好吧,用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

甚至在删除缓存后,速度甚至比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

现在,要提取存档的各个元素,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

这很糟糕,因为它需要读取(并解压缩)整个存档。与之比较:

$ 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

我的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

现在,由于我们已经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

速度更快,但仍然相对较慢,因为归档文件包含几个大块:

$ pixz -tl linux-4.6.tar.pixz
 17648865 / 134217728
 15407945 / 134217728
 18275381 / 134217728
 19674475 / 134217728
 18493914 / 129333248
   336945 /   2958887

因此,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

“不能快速读取索引并不是真正的问题。” 相反,当没有足够的空间或时间甚至无法解压缩文件时,这就是一个阻止因素。建议:'s / Not / Sometimes not /'
agc

1
@agc,另请参见几个附加部分进行编辑。希望它能澄清这一点。您当然不需要额外的磁盘空间来列出存档的内容。
斯特凡Chazelas

1
请原谅我SC,您所添加的内容(尤其是有关磁盘空间和档案列表)被很好地接受了,但是在这里,我主要是指结合包含性的“或”:“没有足够的空间时间”-即包含这两者的集合,非此即彼。有时情况使用户措手不及,而如果没有您描述的预先准备,那么大型客户.tar.gz可能会花费太多时间。特别是在介质较慢的情况下。然后,存档的格式就变成了不可能与实用之间的区别。
agc

@StéphaneChazelas:您的回答很好而且很全面,但是我认为您应该编辑有关pixz的部分-看来该项目很少维护并且有很多问题,因此最好不要将其用于备份重要数据。意见。
Maxxim

3
  1. 尽管有这个缺点,为什么人们仍然使用它呢?

当事态破裂时,公司和学术管理员通常比事态高效运行时受到重视。这样的环境使人们对实验产生了恐惧,并且对新颖性表示轻蔑

  1. 如果我想要“即时内容列表”功能,该有什么选择(我的意思是其他软件/工具)?

dar D isk Ar chiver)具有大量类似 tar的功能,并具有诸如压缩档案的快速随机访问,AKA编目,AKA索引,AKA“即时内容列表”等增强功能。

另请参阅:压缩格式是否对归档中的随机访问有良好的支持?

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.