这是我在 Stack Overflow 上的第一篇文章,我有一个关于使用 GZ 压缩从 TAR 文件中提取单个文件的问题。我不是最擅长 Python 的,所以我可能做错了,任何帮助将不胜感激。
场景:
损坏的*.tar.gz 文件进来,GZ 中的第一个文件包含获取系统SN 的重要信息。这可用于识别机器,以便我们可以向其管理员发出文件已损坏的通知。
问题:
使用常规的 UNIX tar 二进制文件,我能够从存档中提取 README 文件,即使存档不完整并且在完全提取时会返回错误。但是,在 Python 中,我无法只提取一个文件,即使我只指定单个文件,它也总是返回异常。
当前的解决方法:
我正在使用“os.popen”来使用 UNIX tar 二进制文件,以便仅获取 README 文件。
所需的解决方案:
使用 Python tarfile 包仅提取单个文件。
示例错误:
UNIX(工作):
[root@athena tmp]# tar -xvzf bundle.tar.gz README
README
gzip: stdin: unexpected end of file
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now
[root@athena tmp]#
[root@athena tmp]# ls
bundle.tar.gz README
python :
>>> import tarfile
>>> tar = tarfile.open("bundle.tar.gz")
>>> data = tar.extractfile("README").read()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib64/python2.4/tarfile.py", line 1364, in extractfile
tarinfo = self.getmember(member)
File "/usr/lib64/python2.4/tarfile.py", line 1048, in getmember
tarinfo = self._getmember(name)
File "/usr/lib64/python2.4/tarfile.py", line 1762, in _getmember
members = self.getmembers()
File "/usr/lib64/python2.4/tarfile.py", line 1059, in getmembers
self._load() # all members, we first have to
File "/usr/lib64/python2.4/tarfile.py", line 1778, in _load
tarinfo = self.next()
File "/usr/lib64/python2.4/tarfile.py", line 1588, in next
self.fileobj.seek(self.offset)
File "/usr/lib64/python2.4/gzip.py", line 377, in seek
self.read(1024)
File "/usr/lib64/python2.4/gzip.py", line 225, in read
self._read(readsize)
File "/usr/lib64/python2.4/gzip.py", line 273, in _read
self._read_eof()
File "/usr/lib64/python2.4/gzip.py", line 309, in _read_eof
raise IOError, "CRC check failed"
IOError: CRC check failed
>>> print data
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'data' is not defined
Python(处理异常):
>>> tar = tarfile.open("bundle.tar.gz")
>>> try:
... data = tar.extractfile("README").read()
... except:
... pass
...
>>> print(data)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'data' is not defined
请您参考如下方法:
使用手动 Unix 方法,看起来 gzip 将文件解压缩到它中断的位置。
Python gzip(或 tar)模块一旦发现由于 CRC 检查失败导致存档损坏,就会立即退出。
只是一个想法,但您可以使用 gzip 预处理损坏的存档并重新压缩它们以更正 CRC。
gunzip < damaged.tar.gz | gzip > corrected.tar.gz
这将为您提供一个 corrected.tar.gz,它现在将包含所有数据,直到存档被破坏的那一点。您现在应该能够使用 python tar/gzip 库而不会出现 CRC 异常。
请记住,此命令将对存档进行解压缩和 gzip 压缩,这会消耗存储 IO 和 CPU 时间,您不应该对所有存档都这样做。
为了提高效率,您应该只在收到 IOError: CRC check failed 异常时运行它。
