【发布时间】:2013-04-15 10:48:07
【问题描述】:
我正在将我的备份脚本从 shell 转换为 Python。我的旧脚本的功能之一是通过执行以下操作检查创建的 tarfile 的完整性: gzip -t 。
这在 Python 中似乎有点棘手。
似乎唯一的方法是读取 tar 文件中的每个压缩的 TarInfo 对象。
有没有一种方法可以检查 tar 文件的完整性,而无需解压到磁盘或将其保存在内存中(完整地)?
freenode 上#python 上的好人建议我应该逐块读取每个 TarInfo 对象,丢弃读取的每个块。
我必须承认我不知道该怎么做,因为我刚刚开始使用 Python。
假设我有一个 30GB 的 tarfile,其中包含从 1kb 到 10GB 的文件...
这是我开始写的解决方案:
try:
tardude = tarfile.open("zero.tar.gz")
except:
print "There was an error opening tarfile. The file might be corrupt or missing."
for member_info in tardude.getmembers():
try:
check = tardude.extractfile(member_info.name)
except:
print "File: %r is corrupt." % member_info.name
tardude.close()
这段代码远未完成。我不敢在一个巨大的 30GB tar 存档上运行它,因为在某一时刻,检查将是 10+GB 的对象(如果我在 tar 存档中有这么大的文件)
奖金: 我尝试手动破坏 zero.tar.gz(十六进制编辑器 - 编辑几个字节的中间文件)。第一个except没有捕获IOError...这是输出:
Traceback (most recent call last):
File "./test.py", line 31, in <module>
for member_info in tardude.getmembers():
File "/usr/lib/python2.7/tarfile.py", line 1805, in getmembers
self._load() # all members, we first have to
File "/usr/lib/python2.7/tarfile.py", line 2380, in _load
tarinfo = self.next()
File "/usr/lib/python2.7/tarfile.py", line 2315, in next
self.fileobj.seek(self.offset)
File "/usr/lib/python2.7/gzip.py", line 429, in seek
self.read(1024)
File "/usr/lib/python2.7/gzip.py", line 256, in read
self._read(readsize)
File "/usr/lib/python2.7/gzip.py", line 320, in _read
self._read_eof()
File "/usr/lib/python2.7/gzip.py", line 342, in _read_eof
hex(self.crc)))
IOError: CRC check failed 0xe5384b87 != 0xdfe91e1L
【问题讨论】:
-
我已经尝试了包含大量文件的 tarfile 模块,问题是 tarfile.TarFile 模块将所有读取(或写入)成员存储到它的“成员”中。因此,当您有意读取包含大量小文件的 tarbomb 时,会占用大量内存。
标签: python error-handling integrity tarfile