2015-08-18 36 views
2

我正在尋找一種方法,可以將一些Python對象浸泡到組合的tar歸檔文件中。此外,我還需要使用np.save(....)在同一個存檔中保存一些numpy數組。 corse,我也需要稍後閱讀。將數據直接寫入tar檔案

所以我試過是

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' 

Simlar問題,如果我醃的焦油文件的對象。有什麼建議麼?如果更容易,json-pickle也可以工作。

編輯:正如在評論中提到的我混淆了np.save()的參數。然而,這並不能解決問題,因爲現在我得到的錯誤:

object of type 'NoneType' has no len() 

編輯2:如果沒有解決上述問題,你知道的時間內有效地boundle文件的任何其他方式?

+1

一方面,所述參數['np.save'](http://docs.scipy.org/doc/numpy/reference/generated/numpy.save .html)是錯誤的方法。第一個需要是一個打開的文件對象或一個字符串,但是你要給它一個'a',這是一個'np.ndarray'。 –

+0

謝謝!我編輯了問題 –

+1

'np.save'返回'None'。 –

回答

4

首先,我不是一個專家tar用戶,但我可以指出,幾件事情:

a = np.linspace(1,10,10000)  

tar = tarfile.open(fileName, "w") 

如果你想將文件添加到現有的文件,使用「一」模式(或研究可用模式)。 「W」創建一個新的空白文件:

tarinfo = tarfile.TarInfo.frombuf(np.save(a, fileName)) 

的正確使用np.save已經提到。

A 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問題 - python write string directly to tarfile - 顯示可以使用字符串緩衝區直接寫入tar文件。從接受的答案:

# 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.saveStringIO緩衝區,但我不得不檢查/測試,以確保萬無一失。對於普通陣列,save寫入一個包含大小,形狀,dtype信息的標題,然後添加陣列的數據緩衝區。對於其他物體和陣列,則使用pickle

我建議讓文件得到一個正規的np.save,然後addfile工作。然後看看寫入字符串緩衝區是否有效,以及是否節省時間。


這是一個測試腳本。它將一個數組寫入一個tar文件,關閉並重新打開文件並寫入另一個文件,最後提取文件並加載它們。返回的形狀看起來很好。我沒有看過是否可以將這些文件提取到內存緩衝區。

np.savez可以做壓縮歸檔(而不是焦油)相同的事情。

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