Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does json.dump() append to file?

Tags:

python

json

I'm getting some unexpected behavior with json.dump(). I'm creating a file results(empty), and then using it in the code like this:

        with open(results, 'r+') as fp:
            temp = {}
            try:
                # file not empty, load existing dict, and add a key value to it
                temp = json.load(fp)
                temp[key] = value
            except json.decoder.JSONDecodeError:
                # file is empty, create a new dict 
                temp[key] = value
            # write the dictionary back into file
            json.dump(temp, fp)

If the above quote executes once, it works fine. However, if I execute it twice, I'm expecting to have a single dictionary with two keys: {key1: value1, key2: value2}, but I get instead two dictionaries: {key1: value1}{key2: value2}. What could be the reason for such behavior?

like image 608
kck Avatar asked Feb 06 '23 02:02

kck


1 Answers

Look at the output file before and after running the code, and you should see what's going on.

Right before the json.dump, the file object points to the end of the file. You then dump data from this position.

If you try rewinding the file first, it should overwrite the data from the start:

fp.seek(0)
json.dump(temp, fp)

However, this could potentially leave dangling data beyond the first object, if it writes less data than is already in the file. I therefore suggest you restructure your code to read and write the file in two operations, wiping the file on the write. For example:

import json

filename = "foo"

print("Reading %s" % filename)
try:
    with open(filename, "rt") as fp:
        data = json.load(fp)
    print("Data: %s" % data)
except IOError:
    print("Could not read file, starting from scratch")
    data = {}

# Add some data
data["key2"] = "value2"

print("Overwriting %s" % filename)
with open(filename, "wt") as fp:
    json.dump(data, fp)
like image 108
csl Avatar answered Feb 08 '23 14:02

csl