バックアップ スクリプトをシェルから Python に変換する作業を行っています。私の古いスクリプトの機能の 1 つは、 gzip -t を実行して、作成された tarfile の整合性をチェックすることでした。
これは Python では少し難しいようです。
これを行う唯一の方法は、tarfile 内の圧縮された TarInfo オブジェクトをそれぞれ読み取ることです。
ディスクに抽出したり、メモリに (全体として) 保持したりせずに、tarfile の整合性をチェックする方法はありますか?
#python on freenode の善良な人々は、各 TarInfo オブジェクトをチャンクごとに読み取り、読み取ったチャンクを破棄することを提案しました。
Python を始めたばかりなので、これを行う方法がわからないことを認めなければなりません。
1kb から 10GB までの範囲のファイルを含む 30GB の tarfile があると想像してください...
これは私が書き始めた解決策です:
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()
このコードはまだ完成していません。30 GB の巨大な tar アーカイブでこれを実行することは敢えてしません。ある時点で、check は 10 GB 以上のオブジェクトになるためです (tar アーカイブ内にそのような巨大なファイルがある場合)。
おまけ: zero.tar.gz を手動で破損してみました (16 進エディター - 数バイトの中間ファイルを編集)。最初の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