2012-02-29 104 views
4

我有一個程序,它的輸出保存到一個tar.bz2文件,因爲它的工作原理。我有一個處理該數據的Python腳本。如何從Python中損壞的tar.bz2文件中讀取數據?

我希望能夠處理輸出,如果第一個程序中斷 - 或者只是在進程正在進行時對其運行python腳本。

當然,最終的bzip2塊沒有完成,所以它不能被讀取 - 它被有效地破壞了,雖然它真的被截斷了。實際上,GNU tar會高興地提取文件的所有內容 - 就像bzcat那樣。 bzip2recover可以創建修復塊,雖然它在這種情況下真的比bzcat更有用。

但我試圖使用Python的標準tarfile模塊。這種失敗

File "/usr/lib64/python2.7/tarfile.py", line 2110, in extractfile 
    tarinfo = self.getmember(member) 
    File "/usr/lib64/python2.7/tarfile.py", line 1792, in getmember 
    tarinfo = self._getmember(name) 
    File "/usr/lib64/python2.7/tarfile.py", line 2361, in _getmember 
    members = self.getmembers() 
    File "/usr/lib64/python2.7/tarfile.py", line 1803, in getmembers 
    self._load()  # all members, we first have to 
    File "/usr/lib64/python2.7/tarfile.py", line 2384, in _load 
    tarinfo = self.next() 
    File "/usr/lib64/python2.7/tarfile.py", line 2319, in next 
    self.fileobj.seek(self.offset) 
EOFError: compressed file ended before the logical end-of-stream was detected 

當我嘗試對我知道是在開始一個文件中使用TarFile.extractfile。 (tar -xf tarfile.tar.bz2 filename將提取它就好了。)

有沒有什麼聰明的我可以做的忽略無效的文件結束和我的工作?

數據集可能變得相當大,而且非常非常可壓縮,因此保持它不被壓縮是不可取的。

(我找到了存在的問題Untar archive in Python with errors,但在這種情況下,用戶試圖os.system tar文件。)

回答

1

似乎存在兩種可能性。首先,也是最有可能的:

如果ignore_zeros是假,把一個空塊作爲 歸檔的結尾。如果它爲True,則跳過空(無效)塊,並嘗試儘可能多地獲得儘可能多的成員。這僅適用於閱讀 級聯或損壞的檔案。

其次:

對於特殊用途,存在對模式的第二格式: 'FILEMODE | [壓縮]'。 tarfile.open()將返回一個TarFile對象,該對象將其數據作爲一個塊流進行處理。文件不會隨意查找。如果給出,fileobj可能是任何具有read()或write()方法的對象(具體取決於模式)。 bufsize指定塊大小,默認值爲20 * 512字節。結合使用此變體與例如sys.stdin,套接字文件對象或磁帶設備。但是,這樣的TarFile對象是有限的,因爲它不允許隨機訪問

當文件不完整時,聲音就像訪問文件流一樣有用。

+0

謝謝。我會嘗試,但它需要重新考慮我的代碼。顯然'extractfile'然後遍歷這些行會產生向後搜索。 – mattdm 2012-02-29 01:48:58