【问题标题】:Transparently mount a tar.gz archive with Python使用 Python 透明地挂载 tar.gz 存档
【发布时间】:2014-06-16 19:28:56
【问题描述】:

如何使用 Python 透明地挂载 tar.gz 存档?

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

这就是为什么我想尝试透明地安装存档而不完全解压缩它。我遇到了archivemount,这似乎正是我想要的。 有没有办法在纯 Python 中完成 archivemount 的工作? 请不要 subprocess.call “解决方案”。它应该在 64 位 Linux 上运行。

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

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

【问题讨论】:

  • 我认为使用 archivemount 是最简单的方法。它在各种发行版中很容易获得,您只需要 1 个命令即可安装存档。 fusepy 已经 2 年没碰过了。根据您的具体需求,tarfile 本身就足够了。
  • 你提到使用tarfile暴露内容之后。这是焦油里面的焦油吗?
  • @DanGetz 好点,我编辑了问题以使其更清晰。我想先使用tarfile 访问存档,然后使用fusepy 创建文件系统。
  • 您确定使用 TarFile.extractfile() 将文件读入内存不足以满足您的工作要求吗?
  • @DanGetz 是的,非常确定。内容必须由外部程序读取,该程序需要存档的内容,就好像它们是在文件系统(包括文件夹层次结构)中提取的一样。我不控制阅读器模块,因此不能简单地添加对阅读档案的支持。而且我事先不知道它会打开哪些文件,所以我需要给它一切。

标签: python archive tar fuse


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-03-20
    • 1970-01-01
    • 2021-01-09
    • 2023-03-08
    • 2023-04-02
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多