我试图在一个步骤中将对象写入gzip压缩的json文件(最小化代码,并可能节省内存空间).我最初的想法(python3)是这样的:
import gzip, json
with gzip.open("/tmp/test.gz", mode="wb") as f:
json.dump({"a": 1}, f)
Run Code Online (Sandbox Code Playgroud)
然而TypeError: 'str' does not support the buffer interface,这失败了:我认为这与字符串没有被编码为字节有关.那么这样做的正确方法是什么?
我不满意的当前解决方案:
以文本模式打开文件可以解决问题:
import gzip, json
with gzip.open("/tmp/test.gz", mode="wt") as f:
json.dump({"a": 1}, f)
Run Code Online (Sandbox Code Playgroud)
但是我不喜欢文本模式.在我看来(也许这是错误的,但受此支持),文本模式用于修复行尾.这不应该是一个问题,因为json没有行结尾,但我不喜欢它(可能)搞乱我的字节,它(可能)更慢,因为它正在寻找行结束来修复,并且(最坏的)所有)我不明白为什么关于行结尾的东西修复了我的编码问题?
我有一堆json对象需要压缩,因为它占用了太多的磁盘空间,大约20 gigs价值几百万.
理想情况下,我想要做的是单独压缩每个,然后当我需要读取它们时,只需迭代加载和解压缩每个.我尝试通过创建一个文本文件来做到这一点,每个行都是通过zlib压缩的json对象,但这是失败的
decompress error due to a truncated stream,
我认为这是由于包含新行的压缩字符串.
有人知道这样做的好方法吗?
这是有关如何json.dumps用于写入gzip文件的绝佳答案。我想做的是使用dump方法代替直接将json序列化为GzipFile对象。
示例代码:
import gzip, json
data = # a dictionary of data here
with gzip.open(write_file, 'w') as zipfile:
json.dump(data, zipfile)
Run Code Online (Sandbox Code Playgroud)
引发的错误是
TypeError: memoryview: a bytes-like objet is required, not 'str'
Run Code Online (Sandbox Code Playgroud)
我相信是由于gzip write()方法想要将字节对象传递给它而引起的。根据文档,
json模块总是产生str对象,而不是byte对象。因此,fp.write()必须支持str输入。
有没有一种方法来包装json串输出为字节,这样GzipFile的write()将处理它?还是使用该方法json.dumps并将encode()结果字符串转换为bytes对象的唯一方法,如其他链接的答案一样?
编辑:我已经看到了 SA 上关于此问题的所有问题,它们都给了我我在这里询问的错误 - 请您将其保持打开状态以便我可以获得一些帮助吗?
我有一个可以使用 Bash 非常简单地读取的文件,如下所示:
gzip -d -c my_file.json.gz | jq .
这确认它是有效的 JSON。但是当我尝试使用 Python 来读取它时,如下所示:
import json
import gzip
with gzip.open('my_file.json.gz') as f:
data = f.read() # returns a byte string `b'`
json.loads(data)
Run Code Online (Sandbox Code Playgroud)
我收到错误:
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 1632)
Run Code Online (Sandbox Code Playgroud)
但我知道它是来自我的 Bash 命令的有效 JSON。我已经被这个看似简单的问题困扰了很长一段时间,并尝试了一切感觉。有人可以帮忙吗?谢谢。