【发布时间】:2021-10-19 15:27:43
【问题描述】:
我是 python 新手。所以如果我不是用pythonic方式问问题,请原谅。
我的要求如下:
-
我需要编写python代码来实现这个需求。
-
将读取 60 个 json 文件作为输入。每个文件大约 150 GB。
-
所有 60 个 json 文件的示例结构如下所示。请注意,每个文件只有一个 json 对象。而每个文件的巨大大小是因为那个巨大的json对象中包含的“array_element”数组的数量和大小。
{ "string_1":"abc", "string_1":"abc", "string_1":"abc", "string_1":"abc", "string_1":"abc", "string_1":"abc", “数组元素”:[] }
-
转换逻辑很简单。我需要合并所有 60 个文件中的所有 array_element 并将其写入一个巨大的 json 文件。这几乎是 150GB X 60 将是输出 json 文件的大小。
我请求您帮助解决的问题:
-
阅读:计划使用“ijson”模块的 ijson.items(file_object, "array_element")。您能否告诉我 ijson.items 是否会从 json 文件中的“array_element”数组中一次“生成”(即不将整个文件加载到内存中)一个项目?我不认为 json.load 在这里是一个选项,因为我们无法在内存中保存如此庞大的字典。
-
对于写作:我打算使用 ijson.item 读取每个项目,并执行 json.dumps 以“编码”,然后使用 file_object.write 将其写入文件而不使用 json.dump,因为我不能拥有这样的内存中的巨大字典使用 json.dump。您能否告诉我是否需要在下面显示的代码中应用 f.flush() ?据我了解,内部缓冲区在满时会自动刷新,内部缓冲区的大小是恒定的,不会动态增长到内存超载的程度?请告诉我
-
对于增量读取和写入巨大的 json 文件,是否有比上述方法更好的方法?
代码 sn-p 显示上述读写逻辑:
for input_file in input_files:
with open("input_file.json", "r") as f:
objects = ijson.items(f, "array_element")
for item in objects:
str = json.dumps(item, indent=2)
with open("output.json", "a") as f:
f.write(str)
f.write(",\n")
f.flush()
with open("output.json", "a") as f:
f.seek(0,2)
f.truncate(f.tell() - 1)
f.write("]\n}")
希望我已经清楚地提出了我的问题。提前致谢!!
【问题讨论】:
-
关于1.,试试吧。关于 2.,
flush不是必需的。该文件将在with块的末尾关闭,因此所有 Python 缓冲区都将被刷新。关于 3.,您没有具体说明“更好”是什么意思。答案将是主观的,请参阅Subjective question on Stack Overflow。 -
@H.Rittich 感谢您分享您的想法!
标签: json python-3.x out-of-memory in-memory