读取python

时间:2016-10-02 20:00:58

标签: python lz4

我有大量以lz4格式压缩的推文数据。我想打开每个文件并解压缩,并从python中提取一些信息。

当我在Ubuntu中使用lz4c -d命令解压缩文件时,文件解压缩就好了。但是当我在python中使用lz4.loads('path_to_file')时,它会抱怨ValueError: corrupt input at byte 6。当我尝试以字节模式读取()文件时,会发生相同的错误消息。我该怎么办?

4 个答案:

答案 0 :(得分:1)

使用未压缩数据的大小为您的压缩数据添加前缀,或者尝试升级到更高版本的python-lz4包,它可以更好地指定未压缩的数据大小。

无论哪种方式,您都需要事先了解未压缩数据的大小。

请注意,如果您只是解压缩刚刚压缩的内容,那么它将正常工作,因为压缩器会以压缩数据的未压缩大小为前缀。

继续阅读我的具体案例的细节......

我使用的是Ubuntu 16.04.1LTS,发现无论是使用标准的python-lz4包还是使用标准pip导入都没有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选择在两者不匹配时抛出异常

我不知道该决定背后的背景,但在我的情况下,当我不知道预先解压缩的数据大小时,这还不是很有用。

答案 1 :(得分:1)

python-lz4 package包含LZ4库的块和框架API的绑定。不推荐使用的loads方法用于读取LZ4压缩数据的原始块。这可能不是你想要做的 - LZ4文件将使用帧格式进行压缩。

从版本0.19.1开始,python 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.

允许您读取文件并以块的形式处理它。这样就无需将整个文件保存在内存中,也无需将整个文件解压缩到磁盘上。另一方面,如果您确实想要填写完整的文件,只需在上面的size调用中未指定.read()

更多信息可在documentation

中找到

除此之外:我是python lz4绑定的维护者,所以如果遇到问题,或者文档不清楚,请在project page处提出问题。

答案 2 :(得分:0)

lz4.loads()解压缩传递给它的字符串,而不解压缩该字符串中的文件路径。看起来这个库似乎不支持打开文件,因此您必须自己阅读数据。

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

答案 3 :(得分: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.....