2016-10-02 43 views
0

私は膨大な数のツイートデータをlz4形式で圧縮しています。私は各ファイルを開いて解凍し、Pythonからいくつかの情報を抽出したいと思います。pythonで* .lz4ファイルを読む

Ubuntuでlz4c -dコマンドを使用してファイルを解凍すると、ファイルの解凍がうまくいきます。しかし、私がlz4.loads('path_to_file')をPythonで使うと、それはValueError: corrupt input at byte 6という文句を言います。ファイルをバイトモードで読み込もうとすると、同じエラーメッセージが表示されます。私は何をしますか?

答えて

0

lz4.loads()は、渡された文字列を解凍し、その文字列のファイルパスは解凍しません。このライブラリはファイルを開くことをサポートしているようではないので、自分でデータを読む必要があります。

lz4.loads(open('path_to_file', 'rb').read()) 
+0

私は同じバイトエラー、ValueErrorを取得します:バイト10で入力が壊れています:(ファイルを読むときにバイトエラーをバイパスするにはどうすればよいですか? – pandagrammer

+0

コマンドラインツールを使用してデータを圧縮解除しますそれはそこから読んでください。これはPythonライブラリが大きなデータファイルを意味するとは思われません(これはTwitterデータなので、あなたが持っていると思います)。 – kichik

0

代わりlz4toolsパッケージを試してみてください:https://pypi.python.org/pypi/lz4tools

私のテストはlz4

>>> lz4.loads(open("test.js.lz4","rb").read()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: corrupt input at byte 10 

で失敗しかしlz4tools

>>> lz4tools.open("test.js.lz4").read() 
'[{\n "cc_emails": [],\n "fwd_emails": [],\n "reply_cc_emails": [],\n "fr_escalated": false,\n "spam": false,\n "emai..... 
1

で動作するいずれかのサイズを使用して圧縮されたデータの前に付けます圧縮されていないデータの圧縮されていないデータサイズを指定するより良い方法があるpython-lz4パッケージのそれ以降のバージョンにアップグレードしてみてください。

どちらの方法でも、前の非圧縮データのサイズを知る必要があります。

圧縮したものだけを圧縮解除している場合は、圧縮されたデータの圧縮されていないサイズの前にコンプレッサーが付いているため、機能します。

私はUbuntuの16.04.1LTSを使用しています...私の特定のケースについての詳細は

をお読みおよび標準のpython-LZ4パッケージを使用していないか、輸入標準ピップを使用してどちらのpythonの賢明な作業バージョンを持っていたことが分かりましたlz4パッケージ。 、

Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import lz4 
>>> x = '\xb3\x1a\x00\x10\x005\x08\x00\x00\x00\x00\xff\x01\x00\x80\xf7\xae\xe9\x8fP\x8b\xa5\x14\x1a\x00\x196\x1a\x00\x80\x19\xbd\xe9\x8fP\x8b\xa5\x14' 
>>> from struct import * 
>>> len(x) 
38 
>>> # Guess 50 for the size of the uncompressed string ?? 
... 
>>> block = pack('<I', 50) + x 
>>> y = lz4.decompress(block) 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
ValueError: corrupt input at byte 31 
>>> # Try a bigger value 
... 
>>> block = pack('<I', 8192) + x 
>>> y = lz4.decompress(block) 
>>> len(y) 
8192 

が、今常にlz4.decompress私は推測のサイズを返します。これらのバージョンでの解凍方法は、解凍メッセージの正確なサイズを必要とするため

は私が賢明と言うと、それは実際のデータの前に付ける必要がありますつまり、圧縮解除されたデータの実際のサイズを判断できません。

私はhttps://github.com/python-lz4/python-lz4からpython-lz4をクローニングし、ビルドしてから、結果として得られるpythonパッケージを使用しました。これは私に改良を与えた

enter codePython 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import lz4 
>>> x = '\xb3\x1a\x00\x10\x005\x08\x00\x00\x00\x00\xff\x01\x00\x80\xf7\xae\xe9\x8fP\x8b\xa5\x14\x1a\x00\x196\x1a\x00\x80\x19\xbd\xe9\x8fP\x8b\xa5\x14' 
>>> # I know that the decompressed data will never be greater then 8192 bytes 
... 
>>> lz4.block.decompress(x, 8192) 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
ValueError: Decompressor wrote 52 bytes, but 8192 bytes expected from header 
>>> # Now I know the size required, albeit not programmatically, so ... 
... 
>>> lz4.block.decompress(x, 52) 
'\x1a\x00\x10\x005\x08\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xf7\xae\xe9\x8fP\x8b\xa5\x14\x1a\x00\x10\x006\x08\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x19\xbd\xe9\x8fP\x8b\xa5\x14' 

ので、このパッケージの最新バージョンは、パラメータとして、非圧縮データのサイズを取り、それは私の実際のサイズを伝えることができますが、唯一の例外メッセージに。

python-lz4ライブラリからのlz4 Cライブラリへの呼び出しは、必要以上に圧縮解除されたサイズを与えると実際には成功しますが、python-lz4は例外をスローすることを選択します一致。

私はその決定の背後にある背景を知らないのですが、私の場合、圧縮解除されたデータサイズがわからないときは、これはまだ完全には役に立ちません。

0

python-lz4 packageには、LZ4ライブラリのブロックAPIとフレームAPIの両方のバインドが含まれています。推奨されないloadsメソッドは、LZ4圧縮データの生のブロックを読み込むためのものです。これはおそらくあなたがやりたいことではありません.LZ4ファイルはフレームフォーマットを使用して圧縮されます。

のpython LZ4パッケージはこのように、バッファリングとLZ4圧縮されたファイルを読み込むための完全なサポートを持っているバージョン0.19.1のとおり:

import lz4.frame 
chunk_size = 128 * 1024 * 1024 
with lz4.frame.open('mybigfile.lz4', 'r') as file: 
    chunk = file.read(size=chunk_size) 
    # Do stuff with this chunk of data. 

あなたがファイルを読み込み、チャンクでそれを処理することを可能にします。これにより、ファイル全体をメモリに保持したり、ファイル全体をディスクに展開したりする必要がなくなります。一方、フルファイルをスラップしたい場合は、上記の.read()への呼び出しでsizeを指定しないでください。

詳細についてはdocumentationをご覧ください。

その他:私はPythonのlz4バインディングの管理者です。問題が発生した場合、またはドキュメントが不明な場合は、project pageに問題を提出してください。