简体   繁体   中英

Editing a JSON file with new information in Python

I'm trying to edit a meta file with new information generated with a python script and don't want to just append the information with a new JSON object, but rather update the read information.

As input I have something like this:

{
    "foo1": [
    {
      "bar1": 0,
      "bar2": 1337
    },
    ...
}

So far my code reads the information and stores it in a dictionary. After that the information in this file is deleted and replaced with the updated dictionary. The Code is as shown below:

...
outputData = {"foo2": [{"bar3": True, "bar4": 123}]}
with open(metaFile, 'r+') as f:
    metaData = json.load(f)
    f.seek(0)
    f.truncate()
    metaData.update(outputData)
    f.write(json.dumps(metaData, indent=2))
    f.close()
...

As a result this comes out as expected:

{
    "foo1": [
    {
      "bar1": 0,
      "bar2": 1337
    }
  ],
    "foo2":[
    {
      "bar3": true,
      "bar4": 123
    }
  ]
}

Now to my exact question, is it possible to edit the file in such a way, that the content in the file doesn't get deleted at first and written again? Because if something happens with the metaData after the initialization, the information is just gone. Changing the 'r+' argument to 'w+' (+ is optional) will create a new file instead reading from it first and the whole data is gone at this point. With 'a' the outputData cannot be updated and then added, because it would rewrite the already given information. Without updating the metaData it will just create a new object and that's not what I had in mind.

In your case, if you are sure the file size after your changes will always be equal or bigger in size then what's currently in the file, you can call f.write(data) directly. This way, you don't have to truncate (and lose) the file before writing it.

Also, when you open a file using the with syntax, it will be automatically closed once the with block ends.

In the end you code would look something like this:

outputData = {"foo2": [{"bar3": True, "bar4": 123}]}
with open(metaFile, 'r+') as f:
    metaData = json.load(f)
    f.seek(0)
    metaData.update(outputData)
    f.write(json.dumps(metaData, indent=2))
# rest of your code with the normal identation level

You can code as follows, or use MongoDB alternatively.

outputData = {"foo2": [{"bar3": True, "bar4": 123}]}
with open(metaFile, 'r+') as fp:
    origin = fp.read()
    target = json.dumps(dict(json.loads(origin), **outputData), indent=2)
    index = [i for i, (a, b) in enumerate(zip(origin, target)) if a != b][0]
    fp.seek(index)
    fp.truncate()
    fp.write(target[index:])
    fp.close()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM