繁体   English   中英

在python3中解码压缩文件

[英]Decoding a compressed file in python3

所以,我正在压缩一个JSON文件。

import json
import gzip
with open('big.json','r') as fid_json:
    # get json as type dict
    json_dict = json.load(fid_json)
    # convert dict to str
    json_str = str(json_dict)
    json_bytes = bytes(json_str,'utf8')
x = gzip.compress(json_bytes)

那么我可以解码压缩的字节文件吗?我正在尝试这个

json_str = x.decode('utf-8')

但这会给出错误。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

我想我在做一些理论上的错误或者我可以解码压缩文件? 我怎样才能获得压缩的JSON文件,因为我只想压缩JSON? 我正在使用python3。

你做错了两件事:

  • 您正在尝试将压缩数据视为UTF-8。 它不是UTF-8,它是二进制数据。 首先解压缩, 然后解码为UTF-8。

  • 您没有创建压缩的JSON。 您正在创建压缩的Python数据表示 如果要编写压缩的JSON,请不要将JSON解码为Python。

您可以直接压缩JSON数据而无需解码; 我将它直接分到输出文件,以保持内存使用效率:

import gzip
import shutil

with open('big.json', 'rb') as fid_json, gzip.open('big.json.gz', 'wb') as out:
    shutil.copyfileobj(fid_json, out)

请注意,我打开输入文件为二进制文件 ,没有理由解码来自UTF-8的数据只是为了压缩它(在文本模式下打开文件会这样做)。

要使用Python再次解码压缩的JSON,只需再次使用gzip.open()函数打开gzip文件,这次是在文本模式下:

import gzip
import json

with gzip.open('big.json.gz', 'r', encoding='utf8') as fid_json:
    data = json.load(fid_json)

gzip.open()返回的GZIP文件对象为您处理压缩和UTF-8解码; json.load()函数可以从那里解压缩包含的JSON文档。

显式声明文件的编码始终是一个好主意,而不是依赖于为打开的每个文件正确设置的语言环境。 也就是说,从Python 3.6开始, json.load()也接受二进制输入,并检测使用了什么UTF编码,因此在这种情况下使用:

import gzip
import json

with gzip.open('big.json.gz') as fid_json:
    data = json.load(fid_json)

其中默认模式为rb

根本不需要使用json模块:您可以简单地压缩JSON文件数据。 但是,通过将JSON加载到Python对象并将其转换回JSON,您可以摆脱多余的空白。 您还可以执行其他转换,例如,确保数据是ASCII安全的。

正如Martijn所说,您应该压缩JSON数据而不是使用JSON数据加载的Python对象的str表示。 要解压缩该数据,您需要调用解压缩方法。 .decode('utf-8') UTF-8字节解码为Unicode字符串对象。

这是一个简短的演示。 为了测试它,我创建了这个小JSON文件。

test.json

[
    {
        "name": "PM 2Ring",
        "id": 4014959
    },
    {
        "name": "Dan ish",
        "id": 6390698
    }
]

这是代码。

import json
import gzip

fname = 'test.json'

# Load JSON data into a Python object
with open(fname) as fid_json:
    json_dict = json.load(fid_json)

#Convert to a single line JSON string, and encode the string to bytes
json_bytes = json.dumps(json_dict).encode('utf-8')
print(json_bytes)

print('Compressed')
x = gzip.compress(json_bytes)
print(x)
print('Length:', len(x))

print('Decompressed')
new_json = gzip.decompress(x).decode('utf-8')
print(new_json)
print('Length:', len(new_json))

# Load it into a Python object
obj = json.loads(new_json)
print(obj)

产量

b'[{"name": "PM 2Ring", "id": 4014959}, {"name": "Dan ish", "id": 6390698}]'
Compressed
b'\x1f\x8b\x08\x00k\x0e1Y\x02\xff\x8b\xaeV\xcaK\xccMU\xb2RP\n\xf0U0\n\xca\xccKW\xd2QP\xcaL\x01\x8a\x98\x18\x18\x9aX\x9aZ\xd6\xea( \x14\xb9$\xe6)d\x16g\xc0\xd5\x98\x19[\x1a\x98YZ\xd4\xc6\x02\x00v4\x00SI\x00\x00\x00'
Length: 77
Decompressed
[{"name": "PM 2Ring", "id": 4014959}, {"name": "Dan ish", "id": 6390698}]
Length: 73
[{'name': 'PM 2Ring', 'id': 4014959}, {'name': 'Dan ish', 'id': 6390698}]

请注意,压缩版本实际上大于压缩数据(尽管两者都小于原始数据)。 在压缩如此少量的数据时可以预料到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM