首先,我不是专家tar
用户,但我可以指出几点:
a = np.linspace(1,10,10000)
tar = tarfile.open(fileName, "w")
如果要将文件添加到现有文件,请使用“a”模式(或研究可用模式)。"w" 创建一个新的空白文件:
tarinfo = tarfile.TarInfo.frombuf(np.save(a, fileName))
的正确使用np.save
已经提到过。
TarInfo
对象不是文件/数据,而是有关文件的信息。该信息位于数据之前的 tar 文件中,位于 512 字节的缓冲区中。 tobuf
根据对象的属性创建这样的缓冲区。 frombuf
解码这样的缓冲区。例如在fromtarfile
方法中使用它:
def fromtarfile(cls, tarfile):
"""Return the next TarInfo object from TarFile object
tarfile.
"""
buf = tarfile.fileobj.read(BLOCKSIZE)
obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors)
obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
return obj._proc_member(tarfile)
所以很明显frombuf
不是你想在这里使用的。
A 2009 SO question -
python write string directly to tarfile
- 表明可以通过使用字符串缓冲区直接写入tarfile。从接受的答案:
# create a `StringIO` object, and fill it
string = StringIO.StringIO()
...
# create `TarInfo` object:
info = tarfile.TarInfo(name="foo")
info.size=len(string.buf)
# use both with `addfile`:
tar.addfile(tarinfo=info, fileobj=string)
我认为你可以做一个np.save
缓冲StringIO
,但我必须检查/测试才能确定。对于普通数组,save
写入一个包含大小、形状、dtype 信息的标头,然后添加数组的数据缓冲区。对于其他对象和数组,它求助于pickle
.
我建议np.save
找一个常客,然后addfile
工作。然后查看写入字符串缓冲区是否有效以及是否可以节省任何时间。
这是一个测试脚本。它将一个数组写入 tar 文件,关闭并重新打开文件并写入另一个数组,最后提取文件并加载它们。返回的形状看起来不错。我还没有研究是否可以将这些文件提取到内存缓冲区。
np.savez
可以做同样的事情 zip 归档(而不是 tar)。
import numpy as np
import tarfile
import io # python3 version
abuf = io.BytesIO()
np.save(abuf, np.arange(100))
abuf.seek(0)
tar=tarfile.TarFile('test.tar','w')
info= tarfile.TarInfo(name='anArray')
info.size=len(abuf.getbuffer())
tar.addfile(tarinfo=info, fileobj=abuf)
tar.close()
abuf = io.BytesIO()
np.save(abuf, np.ones((2,3,4)))
abuf.seek(0)
tar=tarfile.TarFile('test.tar','a')
info= tarfile.TarInfo(name='anOther')
info.size=len(abuf.getbuffer())
tar.addfile(tarinfo=info, fileobj=abuf)
tar.close()
tar=tarfile.TarFile('test.tar','r')
print(tar.getnames())
tar.extractall()
# can I extract to buffers?
tar.close()
a=np.load('anArray')
b=np.load('anOther')
print(a.shape, b.shape)
还
1415:~/mypy$ tar -tvf test.tar
-rw-r--r-- 0/0 480 1969-12-31 16:00 anArray
-rw-r--r-- 0/0 272 1969-12-31 16:00 anOther