Derek 朕會功夫
Derek 朕會功夫

Reputation: 94319

Python can't load JSON created by json.dump

This seems to be a very straightforward problem where I am trying to read a JSON file and modify a few of the fields.

with open("example.json", "r+") as f:
    data = json.load(f)
    # perform modifications to data
    f.truncate(0)
    json.dump(data, f)

It worked the first time I manually created a JSON file and stored the correct JSON file, but by the second time I run the same script it gives me this error:

ValueError: No JSON object could be decoded

Why is that? It surprises me that the json module cannot parse the file created by the module itself.

Upvotes: 5

Views: 1814

Answers (2)

idjaw
idjaw

Reputation: 26578

Based on the code you provided, and what you are trying to do (return the file cursor back to the beginning of the file), you are not actually doing that with f.truncate. You are actually truncating your file. i.e. Clearing the file entirely.

Per the help on the truncate method:

truncate(...)
    truncate([size]) -> None.  Truncate the file to at most size bytes.

    Size defaults to the current file position, as returned by tell().

What you are actually looking to do with returning the cursor back to the beginning of the file is using seek.

The help on seek:

seek(...)
    seek(offset[, whence]) -> None.  Move to new file position.

So, explicitly, to get back to the beginning of the file you want f.seek(0).

For the sake of providing an example of what is happening. Here is what happens with truncate:

File has stuff in it:

>>> with open('v.txt') as f:
...  res = f.read()
...
>>> print(res)
1
2
3
4

Call truncate and see that file will now be empty:

>>> with open('v.txt', 'r+') as f:
...  f.truncate(0)
...
0
>>> with open('v.txt', 'r') as f:
...  res = f.read()
...
>>> print(res)

>>>

Using f.seek(0):

>>> with open('v.txt') as f:
...  print(f.read())
...  print(f.read())
...  f.seek(0)
...  print(f.read())
...
1
2
3
4



0
1
2
3
4


>>>

The long gap between the first output shows the cursor at the end of the file. Then we call the f.seek(0) (the 0 output is from the f.seek(0) call) and output our f.read().

Upvotes: 3

Chris
Chris

Reputation: 2465

You are missing one line, f.seek(0)

with open("example.json", "r+") as f:
    data = json.load(f)
    # perform modifications to data
    f.seek(0);
    f.truncate(0)
    json.dump(data, f)

Upvotes: 1

Related Questions