如何将新元素添加到JSON文件的末尾?

时间:2017-03-03 16:16:06

标签: python json python-3.x

我编写了一些Python代码,用于在JSON文件中保存字典字典,我想在文件末尾添加更多字典(在主字典中),而不必加载和重写所有字典。

以下是一个示例,我的初始文件如下所示:

{ "dict1": {"key1": 1.1, "key2": 1.2}, "dict2": {"key1": 2.1 "key2": 2.2}}

我想在其中添加"dict3": {"key1": 3.1, "key2": 3.2}

{ "dict1": {"key1": 1.1, "key2": 1.2}, "dict2": {"key1": 2.1 "key2": 2.2}, "dict3": {"key1": 3.1, "key2": 3.2}}

我尝试以"a"模式打开该文件但由于结束}而无法正常工作。那么有没有办法覆盖我文件的最后一个字符或更聪明的方法来获得相同的结果?

3 个答案:

答案 0 :(得分:1)

编辑数据文件有点棘手且危险。您必须修补原始文件格式。通常,只需读取整个文件的JSON,添加数据项,然后重新序列化并重写文件就更简单了。但是,出于性能和其他原因,热修补有时是医生订购的。所以:

def append_to_json(filepath, data):
    """
    Append data in JSON format to the end of a JSON file.
    NOTE: Assumes file contains a JSON object (like a Python
    dict) ending in '}'. 
    :param filepath: path to file
    :param data: dict to append
    """

    # construct JSON fragment as new file ending
    new_ending = ", " + json.dumps(data)[1:-1] + "}\n"

    # edit the file in situ - first open it in read/write mode
    with open(filepath, 'r+') as f:

        f.seek(0, 2)        # move to end of file
        index = f.tell()    # find index of last byte

        # walking back from the end of file, find the index 
        # of the original JSON's closing '}'
        while not f.read().startswith('}'):
            index -= 1
            if index == 0:
                raise ValueError("can't find JSON object in {!r}".format(filepath))
            f.seek(index)

        # starting at the original ending } position, write out
        # the new ending
        f.seek(index)
        f.write(new_ending)    

# let 'er rip
newval = {"dict3": {"key1": 3.1, "key2": 3.2}}
append_to_json('data.json', newval)

假设原始数据位于data.json,运行此文件后,该文件将包含:

{ "dict1": {"key1": 1.1, "key2": 1.2}, 
  "dict2": {"key1": 2.1, "key2": 2.2}, 
  "dict3": {"key1": 3.1, "key2": 3.2}}

(这里的JSON输出已经对齐以便于阅读。在文件中,它可能是一个非常长的行。)

请注意,我保持这么简单,因此更容易理解。实际上,您经常会遇到第二种JSON文件:面向记录的文件,它是一个对象数组([ {}, ... {}])。那种风​​格的结尾是']'而不是'}'。这个例程的更加发达的版本也会寻找这种情况。

答案 1 :(得分:0)

我认为你不应该构建一个巨大的JSON字符串。如果它真的“比我的RAM大”,那么你以后怎么去使用呢?

我建议您使用正确的数据库或简单格式,例如每行一个条目(每行只有一个json.dumps(dictitem)):

["dict1", {"key1": 1.1, "key2": 1.2}]
["dict2", {"key1": 2.1, "key2": 2.2}]
["dict3", {"key1": 3.1, "key2": 3.2}]

然后你可以简单地在文件中附加一个条目/行,解析文件也很容易。并且记忆效率高。

with open('data.txt') as f:
    for line in f:
        key, value = json.loads(line)
        ...

答案 2 :(得分:-1)

看看这个,首先打开文件的最后一个字符,然后使用re.sub()代替最后一个'}'与“MyNewDic”'不要忘记额外的'}'最后和额外的','在你开始代替:

>>> s = '{ "dict1": {"key1": 1.1, "key2": 1.2}, "dict2": {"key1": 2.1 "key2": 2.2}}'

>>> re.sub(r'}$',',"dict3": {"key1": 3.1, "key2": 3.2}}',s)

它给出了这个结论:

'{ "dict1": {"key1": 1.1, "key2": 1.2}, "dict2": {"key1": 2.1 "key2": 2.2},"dict3": {"key1": 3.1, "key2": 3.2}}'