更新json文件

5

我有一个 JSON 文件,其中包含一些数据,并且偶尔我会更新这个文件。

我读取这个文件:

with open('index.json', 'rb') as f:
    idx = json.load(f)

然后检查潜在新数据中是否存在某个键,如果该键不存在,则更新文件:
with open('index.json', mode='a+') as f:
    json.dump(new_data, f, indent=4)

然而,这个过程只是创建了一个新的 JSON 对象(Python 字典),并将其附加为输出 JSON 文件中的新对象,使该文件不是有效的 JSON 文件。
有没有简单的方法可以将新数据附加到 JSON 文件中,而不是覆盖整个文件,通过更新初始字典来实现?

2
'w'模式打开文件,而不是附加+写入模式。 - Martijn Pieters
1
有没有实际的理由不重新编写整个文件?这听起来可能会变得很丑陋。此外,底层文件不支持“插入”操作,因此如果您的更新接近开头,您至少必须重写文件的其余部分。 - FatalError
@theta:这不是这样工作的;你可能是通过追加更新了JSON结构,但文件并不同。你需要重写它。 - Martijn Pieters
此外,如果 JSON 不是严格要求,请考虑使用“pickle”。 - Sudipta Chatterjee
好的,谢谢大家。我会覆盖数据,只是不确定是否有更新的方法。 - theta
显示剩余8条评论
1个回答

11

实现你想要的一种方法是在文件中每行写一个JSON对象。我正在使用这种方法,它运作得非常好。

一个好处是你可以更高效地(占用内存)读取文件,因为你可以一次读取一行。如果你需要全部内容,用Python组装一个列表也没问题,但如果不需要,那么你的操作速度会更快,并且还可以进行追加操作。

因此,要最初编写所有对象,你可以这样做:

with open(json_file_path, "w") as json_file:
    for data in data_iterable:
        json_file.write("{}\n".format(json.dumps(data)))

要高效读取(无论文件大小,都会消耗很少的内存):

with open(json_file_path, "r") as json_file:
    for line in json_file:
        data = json.loads(line)
        process_data(data)

更新/追加:

with open(json_file_path, "a") as json_file:
    json_file.write("{}\n".format(json.dumps(new_data)))

希望这可以帮助你 :)


谢谢@kgr,这似乎是个不错的技巧。我猜这样做无法缩进。 - theta
1
@theta - 不用谢。是的,如果您每行存储一个对象,则无法在文件中漂亮地打印JSON(缩进)。不过,您可以在每个JSON对象之后添加一些标记,并使用它来区分一个对象何时结束以及另一个对象何时开始(这里\n是这样的标记,也起着特殊作用)。这将更加棘手,但肯定是可行的。这样,您就可以在文件中拥有缩进,因为换行符将被忽略。整个想法是不要在文件中只有一个JSON对象,而是多个,这样您可以在需要时以有效的方式添加更多内容... - kgr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接