如何从Python中损坏的tar.bz2文件中读取数据?
我有一个程序,它的输出保存到一个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文件。)
似乎存在两种可能性。首先,也是最有可能的:
如果ignore_zeros是假,把一个空块作为 归档的结尾。如果它为True,则跳过空(无效)块,并尝试尽可能多地获得尽可能多的成员。这仅适用于阅读 级联或损坏的档案。
其次:
对于特殊用途,存在对模式的第二格式: 'FILEMODE | [压缩]'。 tarfile.open()将返回一个TarFile对象,该对象将其数据作为一个块流进行处理。文件不会随意查找。如果给出,fileobj可能是任何具有read()或write()方法的对象(具体取决于模式)。 bufsize指定块大小,默认值为20 * 512字节。结合使用此变体与例如sys.stdin,套接字文件对象或磁带设备。但是,这样的TarFile对象是有限的,因为它不允许随机访问
当文件不完整时,声音就像访问文件流一样有用。
谢谢。我会尝试,但它需要重新考虑我的代码。显然'extractfile'然后遍历这些行会产生向后搜索。 – mattdm 2012-02-29 01:48:58