2012-02-29 109 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