Reputation: 94319
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
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
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