我正在寻找一种方法,可以将一些Python对象挑选到组合的tar存档中。此外,我还需要使用np.save(....)
在同一个存档中保存一些numpy数组。对于科西嘉,我还需要稍后阅读。
所以我尝试的是
a = np.linspace(1,10,10000)
tar = tarfile.open(fileName, "w")
tarinfo = tarfile.TarInfo.frombuf(np.save(a, fileName))
tar.close()
我收到错误:
'numpy.ndarray' object has no attribute 'write'
如果我在tar文件中挑选一个对象,我会得到模拟问题。有什么建议?如果它更容易,json-pickle也会起作用。
编辑:正如评论中提到的,我混淆了np.save()的参数。但是,这并没有解决问题,因为现在我收到了错误:object of type 'NoneType' has no len()
编辑2:如果没有上述问题的解决方案,你知道其他任何时间有效绑定文件的方式吗?
答案 0 :(得分:4)
首先,我不是专家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
不是你想在这里使用的。
2009年SO问题 - 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