不行。
tar格式不适合快速提取单个文件。在大多数情况下,这种情况会加剧,因为tar文件通常是在压缩流中的。我建议使用7z。
有点。
如果您知道只有一个文件具有该名称,或者如果您只想要一个文件,则可以在第一次命中后中止提取过程。
例如:
完全扫描该物品。
$ time tar tf /var/log/apache2/old/2016.tar.xz
2016/
2016/access.log-20161023
2016/access.log-20160724
2016/ssl_access.log-20160711
2016/error.log-20160815
(...)
2016/error.log-20160918
2016/ssl_request.log-20160814
2016/access.log-20161017
2016/access.log-20160516
time: Real 0m1.5s User 0m1.4s System 0m0.2s
从内存中扫描该物件
$ time tar tf /var/log/apache2/old/2016.tar.xz > /dev/null
time: Real 0m1.3s User 0m1.2s System 0m0.2s
在第一个文件后中止
$ time tar tf /var/log/apache2/old/2016.tar.xz | head -n1
2016/
time: Real 0m0.0s User 0m0.0s System 0m0.0s
三个文件后中止
$ time tar tf /var/log/apache2/old/2016.tar.xz | head -n3
2016/
2016/access.log-20161023
2016/access.log-20160724
time: Real 0m0.0s User 0m0.0s System 0m0.0s
在“中间”某个文件后终止
$ time tar xf /var/log/apache2/old/2016.tar.xz 2016/access.log-20160724 | head -n1
time: Real 0m0.9s User 0m0.9s System 0m0.1s
在“底部”某个文件后中止
$ time tar xf /var/log/apache2/old/2016.tar.xz 2016/access.log-20160516 | head -n1
time: Real 0m1.1s User 0m1.1s System 0m0.2s
我在这里向您展示,如果您在第一行(head -n1)退出后杀死GNU tar的输出管道(标准输出),则tar进程也会终止。
您可以看到,读取整个存档比在接近存档“底部”的某个文件后中止要花费更多时间。您还可以看到,在遇到顶部的文件后中止读取需要的时间明显较少。
如果我能决定存档的格式,我就不会这样做。
所以...
不要使用Python开发者非常喜欢的列表推导式,而是迭代tar.getmembers()
(或者使用该库提供一个文件一次的任何方法),并在遇到所需结果时中断迭代,而不是将所有文件都展开到列表中。
getmembers()
时,tarfile
会扫描整个文件。尝试迭代tarfile
对象。但是,如果目标文件在结尾处,您仍然可能会扫描整个文件。Tar文件没有随机访问索引。 - dhke