在python3中解码压缩文件
因此,我正在压缩一个JSON文件在python3中解码压缩文件,python,json,compression,python-3.6,Python,Json,Compression,Python 3.6,因此,我正在压缩一个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.c
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
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文件,这次是以文本模式:
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,则您做错了两件事:
- 您试图将压缩数据视为UTF-8。它不是UTF-8,而是二进制数据。首先解压缩,然后解码为UTF-8
- 您没有创建压缩的JSON。您正在创建压缩的Python数据表示形式。如果要编写压缩的JSON,请不要将JSON解码为Python
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文件,这次是以文本模式:
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表示。要解压缩这些数据,需要调用decompress方法.decode('utf-8')
将utf-8字节解码为Unicode字符串对象
这里有一个简短的演示。为了测试它,我创建了这个小小的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)
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}]
请注意,压缩版本实际上比压缩数据大(尽管两者都比原始数据小)。在压缩如此少量的数据时,这是意料之中的 完全不需要使用json模块:只需压缩json文件数据即可。但是,通过将JSON加载到Python对象中并将其转换回JSON,可以消除多余的空白。您还可以执行其他转换,例如确保数据是ASCII安全的
正如Martijn所说,您应该压缩JSON数据,而不是用JSON数据加载的Python对象的str表示。要解压缩这些数据,需要调用decompress方法.decode('utf-8')
将utf-8字节解码为Unicode字符串对象
这里有一个简短的演示。为了测试它,我创建了这个小小的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)
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}]
请注意,压缩版本实际上比压缩数据大(尽管两者都比原始数据小)。在压缩如此少量的数据时,这是意料之中的 为什么要压缩Python表示呢。你不应该使用
json.load()
然后str()
@MartijnPieters好吧,我对这方面还不熟悉。我的目标是压缩JSON。应该采用什么方法?为什么要压缩Python表示。你不应该使用json.load()
然后str()
@MartijnPieters好吧,我对这方面还不熟悉。我的目标是压缩JSON。应该采取什么办法?