4

動作中に出力を tar.bz2 ファイルに保存するプログラムがあります。そのデータを処理する python スクリプトがあります。

最初のプログラムが中断された場合、またはプロセスの進行中に python スクリプトを実行するだけで、出力を処理できるようにしたいと考えています。

もちろん、最後の bzip2 ブロックは未完成であるため、読み取ることはできません。実際には破損していますが、実際には切り詰められているだけです。GNU tar は実際には、その時点までのファイルから可能な限りすべてを喜んで抽出しますbzcatbzip2recover修復されたブロックを作成することもできますが、この場合はbzcat.

しかし、私は Python の標準のtarfileモジュールを使用しようとしています。これは失敗します

  File "/usr/lib64/python2.7/tarfile.py", line 2110, in extractfile
    tarinfo = self.getmember(member)
  File "/usr/lib64/python2.7/tarfile.py", line 1792, in getmember
    tarinfo = self._getmember(name)
  File "/usr/lib64/python2.7/tarfile.py", line 2361, in _getmember
    members = self.getmembers()
  File "/usr/lib64/python2.7/tarfile.py", line 1803, in getmembers
    self._load()        # all members, we first have to
  File "/usr/lib64/python2.7/tarfile.py", line 2384, in _load
    tarinfo = self.next()
  File "/usr/lib64/python2.7/tarfile.py", line 2319, in next
    self.fileobj.seek(self.offset)
EOFError: compressed file ended before the logical end-of-stream was detected

最初にあることがわかってTarFile.extractfileいるファイルで使用しようとしたとき。(問題なく抽出されます。)tar -xf tarfile.tar.bz2 filename

ファイルの無効な終わりを無視して、私が持っているものを操作するために私ができる賢いことはありますか?

データセットはかなり大きくなる可能性があり、非常に圧縮可能であるため、圧縮しないままにしておくことは望ましくありません。

(既存の質問Untar archive in Python with errorsを見つけましたが、その場合、ユーザーはos.systemtar ファイルを試みています。)

4

1 に答える 1

1

2つの可能性があるようです。まず、最も可能性が高いのは次のとおりです。

ignore_zeros が False の場合、空のブロックをアーカイブの最後として扱います。True の場合、空の (無効な) ブロックをスキップして、できるだけ多くのメンバーを取得しようとします。これは、連結されたアーカイブまたは破損したアーカイブを読み取る場合にのみ役立ちます。

第二に:

特別な目的のために、モードの 2 番目の形式があります: 'filemode|[compression]'。tarfile.open() は、データをブロックのストリームとして処理する TarFile オブジェクトを返します。ファイルに対してランダムなシークは行われません。指定された場合、fileobj は (モードに応じて) read() または write() メソッドを持つ任意のオブジェクトです。bufsize はブロックサイズを指定し、デフォルトは 20 * 512 バイトです。このバリアントは、sys.stdin、ソケット ファイル オブジェクト、またはテープ デバイスなどと組み合わせて使用​​します。ただし、そのような TarFile オブジェクトは、ランダムにアクセスできないという制限があります。

ファイルが不完全な場合、ストリームとしてファイルにアクセスすると便利なようです。

于 2012-02-29T01:44:55.940 に答える