python - 使用 Python 透明地挂载 tar.gz 存档

标签 python archive tar fuse

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

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

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

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

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

最佳答案

从我的 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 文件中的偏移量并简单地读取下一个 size 字节。这是可行的,因为 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

关于python - 使用 Python 透明地挂载 tar.gz 存档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23388731/

相关文章:

linux - 使用 --strip-components=1 解压 tar 文件

linux - tar 排除特定路径上的错误输出

python - 为什么我在安装时不断收到此消息说 EntryPoint must be in 'name=module :attrs [extras]

ios - 无法存档更新的 iOS PhoneGap 应用程序

linux - 为什么不能使用 gzip、bzip、bzip2、xz 压缩目录?

cmd - 通过控制台命令将文件夹内容添加到 .rar,而不添加文件夹本身

python - 通过复选框 PyQt 始终处于最前面的行为

python - 在 python 的 sort() 函数的情况下,多态性功能会失败,并且我们如何对 python 中的虚数进行排序?

python - 如果用户输入无效答案如何重做输入

bash - 在不接触磁盘的情况下从 tar.gz 中提取文件