2016-10-02 398 views
0

我有大量的推文數據壓縮爲lz4格式。我想打開每個文件並對其進行解壓縮,並從python中提取一些信息。閱讀python中的* .lz4文件

當我在Ubuntu中使用lz4c -d命令解壓縮文件時,文件解壓縮得很好。但是當我在python中使用lz4.loads('path_to_file')時,它抱怨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包或使用標準的點子有蟒蛇的明智工作版本導入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總是返回我猜大小,這意味着我無法確定解壓縮數據的實際大小。

我採取了克隆python-lz4從https://github.com/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的綁定。已棄用的loads方法用於讀取LZ4壓縮數據的原始塊。這可能不是你想要做的 - LZ4文件將使用幀格式進行壓縮。

隨着版本0.19.1蟒蛇LZ4包有一個用於讀取LZ4壓縮文件具有緩衝,這樣的全面支持:

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上提出問題。