Python tarfile 压缩内存中的一个对象

标签 python

我正在尝试使用 tarfile 在内存中添加一个文件,然后将其写回磁盘,但我遇到的问题是在我的最终输出中,当我提取新创建的 tar.gz 文件时,我得到一个空文件。我的代码哪里做错了?

import tarfile
import io

with open('logo.png', 'rb') as f:
    data = f.read()

fh = io.BytesIO()
with tarfile.open(fileobj=fh, mode='w:gz') as tar:
    info = tarfile.TarInfo('some.png')
    tar.addfile(info, data)

with open('/tmp/test/test.tar.gz', 'wb') as f:
    f.write(fh.getvalue())

我也尝试过执行 tar.addfile(info, fh.write(data)),但这只会创建一个损坏的 tar 文件。

最佳答案

TarFile.addfile() 接受一个类似文件的对象。

当文档说:

tarinfo.size bytes are read from it and added to the archive.

意思是tarinfo.size用来决定读取多少字节。因此,您需要适本地设置tarinfo.size

您唯一需要做的就是从源读取数据,计算长度,然后将该数据加载到 BytesIO 对象中:

例如

import tarfile
import io

with open('logo.png', 'rb') as f:
    data = f.read()
    source_f = io.BytesIO(initial_bytes=data)

fh = io.BytesIO()
with tarfile.open(fileobj=fh, mode='w:gz') as tar:
    info = tarfile.TarInfo('logo.png')
    info.size = len(data)
    tar.addfile(info, source_f)

with open('test.tar.gz', 'wb') as f:
    f.write(fh.getvalue())

或者更高效的内存方式,寻找源文件:

f = open('logo.png', 'rb')
f.seek(0,2) # go to the end
source_len = f.tell()
f.seek(0)

fh = io.BytesIO()
with tarfile.open(fileobj=fh, mode='w:gz') as tar:
    info = tarfile.TarInfo('logo.png')
    info.size = source_len
    tar.addfile(info, f)

with open('test.tar.gz', 'wb') as f:
    f.write(fh.getvalue())

f.close()

关于Python tarfile 压缩内存中的一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59272304/

相关文章:

python - 在 Django REST 控件序列化程序中不会自动删除空格?

python - 托管用于下载 Python Tornado 的静态文件

Python pandas 条件列处理 None

python - 如何使用 psycopg2 在 postgres 中获取表?

python - 相同数据和簇数的不同轮廓分数

python - 包括 numpy random.uniform 的上限

python - 刻度线标签修改;如何在标签上添加任意刻度:

python - 将行值转换为列,并计算所有可能值的重复次数mysql

python - 从特定索引加入列表

python - pdfminer pdf2text 输出 'FF'