2016-10-02 403 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上提出问题。