Remove a JSON file if an exception occurs

Question:

I am writing a program which stores some JSON-encoded data in a file, but sometimes the resulting file is blank (because there wasn’t found any new data). When the program finds data and stores it, I do this:

with open('data.tmp') as f:
    data = json.load(f)
os.remove('data.tmp')

Of course, if the file is blank this will raise an exception, which I can catch but does not let me to remove the file. I have tried:

try:
    with open('data.tmp') as f:
        data = json.load(f)
except:
    os.remove('data.tmp')

And I get this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "MyScript.py", line 50, in run
    os.remove('data.tmp')
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process

How could I delete the file when the exception occurs?

Asked By: bitomic

||

Answers:

you need to edit the remove part, so it handles the non-existing case gracefully.

import os
try:
    fn = 'data.tmp'
    with open(fn) as f:
        data = json.load(f)
except:
    try:
        if os.stat(fn).st_size > 0:
            os.remove(fn) if os.path.exists(fn) else None
    except OSError as e: # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT:
            raise

see also Most pythonic way to delete a file which may not exist

you could extract the silent removal in a separate function.

also, from the same other SO question:

# python3.4 and above
import contextlib, os

try:
    fn = 'data.tmp'
    with open(fn) as f:
        data = json.load(f)
except:
    with contextlib.suppress(FileNotFoundError):
        if os.stat(fn).st_size > 0:
            os.remove(fn)

I personally like the latter approach better – it’s explicit.

Answered By: Jörg Beyer

How about separating out file reading and json loading? json.loads behaves exactly same as json.load but uses a string.

with open('data.tmp') as f:
    dataread = f.read()
os.remove('data.tmp')

#handle exceptions as needed here...
data = json.loads(dataread)
Answered By: JL Peyret

I am late to the party. But the json dump and load modules seem to keep using files even after writing or reading data from them. What you can do is use dumps or loads modules to get the string representation and then use normal file.write() or file.read() on the result.

For example:

with open('file_path.json'), 'w') as file:
    file.write(json.dumps(json_data))

os.remove('file_path.json')

Not the best alternative but it saves me a lot especially when using temp dir.

Answered By: Richard-code-gig
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.