添加到tarfile的文件将作为空文件返回

时间:2018-01-26 12:06:36

标签: python

我正在尝试将文件添加到python中的gzipped tarfile

import tarfile

# create test file
with open("testfile.txt", "w") as f:
    f.write("TESTTESTTEST")

# create archive
with tarfile.open("archfile.tar.gz", "x:gz") as archive:
    with open("testfile.txt", 'rb') as f:
        archive.addfile(tarfile.TarInfo("testfile.txt"), f)

# read test file out of archive
with tarfile.open("archfile.tar.gz", "r:gz") as archive:
    print(archive.extractfile("testfile.txt").read())

结果是b'' - 一个空的字节串。

文件不为空 - 如果我尝试使用以下代码读取文件:

with open("testfile.txt", 'rb') as f:
    print(f.read())

......我得到b'TESTTESTTEST'

有什么东西显而易见我错过了吗?我的最终目标是使用f = io.StringIO('TESTTESTTEST')

在内存中添加字符串

我也尝试删除:gz,我发现原始tar存档存在同样的问题。

有关其他信息 - 我在Windows 10上的jupyter会话中使用Python 3.我在Windows / Python 3.5.2 / PyCharm中看到了同样的问题。

3 个答案:

答案 0 :(得分:1)

您可以使用StringIO模块将内容作为文件对象写入tar文件。

<强>示例:

import tarfile
import StringIO

tar = tarfile.TarFile("archfile.tar.gz","w")
with open("testfile.txt", 'rb') as f:
    s = StringIO.StringIO(f.read())

info = tarfile.TarInfo(name="testfile.txt")
info.size = len(s.buf)
tar.addfile(tarinfo=info, fileobj=s)
tar.close()

答案 1 :(得分:0)

不是一个完美的答案,但我设法用zipfile来解决这个问题。

import zipfile
import io

# create archive
with zipfile.ZipFile("archfile.zip", "w") as archive:
    with io.StringIO("TESTTESTTEST") as f:
        archive.writestr("1234.txt", f.read())

# read test file out of archive
with zipfile.ZipFile("archfile.zip", "r") as archive:
    print(archive.read("1234.txt"))

生成b'TESTTESTTEST'

答案 2 :(得分:0)

我遇到了类似的问题。文档说,当您调用tar.addfile时,它将从给定文件中写入TarInfo.size个字节。这意味着您必须使用文件大小创建TarInfo或使用tar.add()而不是tar.addfile

# create archive V1
with tarfile.open("archfile.tar.gz", "x:gz") as archive:
    with open("testfile.txt", 'rb') as f:
        info = archive.gettarinfo("testfile.txt")
        archive.addfile(info, f)

# create archive V2
with tarfile.open("archfile.tar.gz", "x:gz") as archive:
    archive.add("testfile.txt")

# create archive V3
with tarfile.open("archfile.tar.gz", "w:gz") as archive:
    with io.BytesIO(b"TESTTESTTEST") as f:
        info = tarfile.TarInfo("testfile.txt")
        f.seek(0, io.SEEK_END)
        info.size = f.tell()
        f.seek(0, io.SEEK_SET)
        archive.addfile(info, f)