首页 > 解决方案 > 如何从 gzip 读取 json 字符串

问题描述

我正在尝试从 .gz 文件中读取 json 对象。

这是代码:

with gzip.open("C:/Users/shaya/Downloads/sample.gz", 'rb') as fin:
    json_bytes = fin.read()  
    
json_str = json_bytes.decode('utf-8')
data = json.loads(json_str)
print(data)

我收到此错误:

JSONDecodeError: Extra data: line 1 column 2 (char 1)

json 字符串无法转换为 json 对象。

标签: pythonjsongzip

解决方案


编辑。正如@CharlesDuffy 所建议的,您已将 tar 压缩包压缩为内部带有 JSON 的文件。有关阅读 gzipped tar 的信息,请参阅第二版。第一个版本仅用于阅读 gzip。

第一个版本

我认为您以某种方式错误地压缩/解压缩了 JSON 数据,因为它在解压缩后包含非 JSON 前导字节。

您必须从解压缩的数据中剪切/删除前导的非 JSON 字节,或者像下面的代码一样重新创建数据。对于您的情况,要删除前导错误字节,json_str = json_str[json_str.find('{'):]请先执行json.loads(...).

下面是逐步 json 编码/gzip 压缩/写入文件/从文件读取/gzip 解压缩/json 解码的完整工作代码:

在线尝试!

import json, gzip

# Encode/Write

pydata = {
    'a': [1,2,3],
    'b': False,
}

jdata = json.dumps(pydata, indent = 4)

serial = jdata.encode('utf-8')

with open('data.json.gz', 'wb') as f:
    f.write(gzip.compress(serial))

# Read/Decode
   
serial, pydata, jdata = None, None, None
    
with open('data.json.gz', 'rb') as f:
    serial = gzip.decompress(f.read())
    
jdata = serial.decode('utf-8')

pydata = json.loads(jdata)

print(pydata)

输出:

{'a': [1, 2, 3], 'b': False}

第二版

下面是在 gzipped tar 文件中读取 JSON 的代码。它从 tar 读取第一个 JSON 文件,fname = ...如果有多个 json 文件,您可以替换为 JSON 文件的正确文件名。

import json, gzip, tarfile, io

with open('data.json.tar.gz', 'rb') as f:
    tserial = gzip.decompress(f.read())
    
with tarfile.open(fileobj = io.BytesIO(tserial), mode = 'r') as f:
    fname = [e for e in f.getnames() if e.lower().endswith('.json')][0]
    serial = f.extractfile(fname).read()
    
jdata = serial.decode('utf-8')

pydata = json.loads(jdata)

print(pydata)

推荐阅读