<blockquote>
<p>I tried manually corrupting zero.tar.gz (hex editor - edit a few bytes
midfile). The first except does not catch IOError...</p>
</blockquote>
<p>如果你看一下回溯,你会发现它在你调用<code>tardude.getmembers()</code>时被抛出,所以你需要像。。。</p>
<pre><code>try:
tardude = tarfile.open("zero.tar.gz")
except:
print "There was an error opening tarfile. The file might be corrupt or missing."
try:
members = tardude.getmembers()
except:
print "There was an error reading tarfile members."
for member_info in members:
try:
check = tardude.extractfile(member_info.name)
except:
print "File: %r is corrupt." % member_info.name
tardude.close()
</code></pre>
<p>至于最初的问题,你就快到了。你只需要从<code>check</code>对象中读取数据,比如。。。</p>
<pre><code>BLOCK_SIZE = 1024
try:
tardude = tarfile.open("zero.tar.gz")
except:
print "There was an error opening tarfile. The file might be corrupt or missing."
try:
members = tardude.getmembers()
except:
print "There was an error reading tarfile members."
for member_info in members:
try:
check = tardude.extractfile(member_info.name)
while 1:
data = check.read(BLOCK_SIZE)
if not data:
break
except:
print "File: %r is corrupt." % member_info.name
tardude.close()
</code></pre>
<p>…这将确保一次使用的内存永远不会超过<code>BLOCK_SIZE</code>字节。</p>
<p>另外,你应该尽量避免使用。。。</p>
<pre><code>try:
do_something()
except:
do_something_else()
</code></pre>
<p>…因为它会掩盖意外的异常。试着只捕捉你真正想要处理的异常,比如。。。</p>
<pre><code>try:
do_something()
except IOError:
do_something_else()
</code></pre>
<p>…否则你会发现在你的代码中发现错误更加困难。</p>