Python-将大型JSON数组写入文件

时间:2018-09-02 13:43:01

标签: python json serialization

我正在研究一个可能最终试图将非常大的json数组序列化到文件的过程。因此,将整个阵列加载到内存中,然后仅转储到文件将不起作用。我需要将各个项目流式传输到文件中,以避免出现内存不足的问题。

令人惊讶的是,我找不到执行此操作的任何示例。下面的代码段是我拼凑而成的。有更好的方法吗?

first_item = True
with open('big_json_array.json', 'w') as out:
     out.write('[')
     for item in some_very_big_iterator:
          if first_item:
               out.write(json.dumps(item))
               first_item = False
          else:
               out.write("," + json.dumps(item))
     out.write("]")

1 个答案:

答案 0 :(得分:3)

虽然您的代码合理,但是可以对其进行改进。您有两个合理的选择,以及一个附加建议。

您的选择是:

  • 不生成数组,而是生成JSON Lines输出。对于生成器中的每个项目,这会在文件中写入一个有效的JSON文档,其中没有换行符,后跟换行符。通过默认的json.dump(item, out)配置和后面的`out.write('\ n')可以很容易地生成。您最终得到的是每行都有一个单独的JSON文档的文件。

    优点是您不必担心写入或再次读取数据时的内存问题,否则以后在读取文件中的数据时会遇到更大的问题; json模块不能被迭代地加载数据,除非没有手动跳过初始的[和逗号。

    读取JSON行很简单,请参见Loading and parsing a JSON file with multiple JSON objects in Python

  • 将数据包装在生成器和列表子类中,以使json.dump()接受它作为列表,然后迭代地写入数据。我将在下面概述。考虑到您现在可能需要反向解决问题,再次使用Python 读取 JSON数据。

我的建议是在此处不使用JSON 。 JSON从未为大型数据集设计,它是一种针对较小负载的Web交换格式。这种数据交换有更好的格式。如果您不能偏离JSON,请至少使用JSON行。

您可以使用生成器和list子类来迭代地编写JSON数组,以欺骗json库将其接受为列表:

class IteratorAsList(list):
    def __init__(self, it):
        self.it = it
    def __iter__(self):
        return self.it
    def __len__(self):
        return 1

with open('big_json_array.json', 'w') as out:
    json.dump(IteratorAsList(some_very_big_iterator), out)

IteratorAsList类满足json编码器进行的两项测试:对象是其列表或子类,并且其长度大于0;当满足这些条件时,它将遍历列表(使用__iter__)并对每个对象进行编码。

然后json.dump()函数在编码器产生数据块时将其写入文件;它永远不会将所有输出保存在内存中。