使用Python透明地安装tar.gz存档

时间:2014-04-30 12:57:17

标签: python archive tar fuse

如何使用Python透明地安装tar.gz存档?

我有一个tar.gz存档,其内容必须由外部程序读取。内容只是暂时需要的。我可以将它解压缩到一个临时文件夹,并将我的外部程序指向那里阅读它。之后,我可以再次删除临时文件夹。但是,存档可能很大(提取时大于1 GB),因此解压缩它们会占用磁盘上的大量空间。我的服务器在高清性能上相当薄弱,我不能浪费空间,但它确实有很多RAM和CPU能力。

这就是为什么我想尝试透明地挂载存档而不完全解压缩它。我遇到了archivemount,这似乎完全符合我的要求。 有没有办法在纯Python中执行archivemount所做的事情?请不要使用subprocess.call“解决方案”。它应该在64位Linux上运行。

我认为应该有一种聪明的方法来使用tarfile来访问存档的内容,然后使用fusepy创建一个公开存档内容的用户空间文件系统。有没有人把这些碎片放在一起?有什么想法吗?

如果您认为这不是一个好主意,请发表相关评论。如果您知道哪些更好,请发表评论。

1 个答案:

答案 0 :(得分:0)

从我的ratarmount模块的0.3.1版本开始,您可以使用它或查看其源代码以在Python中安装.tar.gz。寻求gzip的支持来自于依赖项indexed_gzip。 Ratarmount本身基于tarindexer,它实现了使用tarfile来获取偏移量然后寻找偏移量的想法。但是,ratarmount在其他可用性和性能功能中添加了FUSE层。

您可以从PyPI安装ratarmount:

pip3 install --user ratarmount

,然后直接从python调用其命令行界面,如下所示:

import ratarmount
ratarmount.cli( [ '--help' ] )
ratarmount.cli( [ pathToTar, pathToMountPoint ] )

模块的核心就像您已经猜到的tarfile一样,它用于遍历所有TarInfo对象并创建文件路径,偏移量,大小的列表,然后可用于直接查找偏移量在原始tar文件中,只需读取下一个大小的字节即可。之所以可行,是因为TAR就是这么简单的一种格式。

这是未经优化且非常裸露的核心思想:

import sys
import tarfile
from indexed_gzip import IndexedGzipFile

targzfile = sys.argv[1]
filetoprint = sys.argv[2]

index = {} # path : ( offset, size )

file = IndexedGzipFile( targzfile )
for tarinfo in tarfile.open( fileobj = file, mode = 'r|' ):
    index[tarinfo.name] = ( tarinfo.offset_data, tarinfo.size )

# at this point you could save or load the index for faster consecutive file seeks

file.seek( index[filetoprint][0] )
sys.stdout.buffer.write( file.read( index[filetoprint][1] ) )

上面的示例经过测试可用于:

wget -O- 'https://ftp.mozilla.org/pub/firefox/releases/70.0/linux-x86_64/en-US/firefox-70.0.tar.bz2' | bzip2 -d -c | gzip > firefox.tgz
python3 minimal-example.py firefox.tgz firefox/updater.ini