我正在将备份脚本从shell转换为Python。我的旧脚本的一个特性是通过执行以下操作来检查创建的tarfile的完整性:gzip-t。
这在Python中似乎有点棘手。
似乎唯一的方法就是读取tarfile中的每个压缩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存档上运行这个,因为在某一点上,check是一个10+GB的对象(如果我在tar存档中有这么大的文件)
奖金: 我试图手动损坏zero.tar.gz(hex editor-编辑几个字节的midfile)。第一个例外是不捕获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
只是对Aya's答案稍加改进,使其更具习惯性(尽管我正在删除一些错误检查,以使机制更直观):
这实际上只是删除了
while 1:
(有时被认为是一个小代码味道)和if not data:
检查。还要注意,with
的使用将此限制为Python 2.7+您可以使用
subprocess
模块调用文件上的gzip -t
。。。如果
result
不是0,则有问题。不过,您可能需要检查gzip是否可用。我为此写了一个实用函数如果你看一下回溯,你会发现它在你调用
tardude.getmembers()
时被抛出,所以你需要像。。。至于最初的问题,你就快到了。你只需要从
check
对象中读取数据,比如。。。…这将确保一次使用的内存永远不会超过
BLOCK_SIZE
字节。另外,你应该尽量避免使用。。。
…因为它会掩盖意外的异常。试着只捕捉你真正想要处理的异常,比如。。。
…否则你会发现在你的代码中发现错误更加困难。
相关问题 更多 >
编程相关推荐