Safely modify a file in place -- am I doing it right?

Grant Edwards invalid at invalid.invalid
Wed Jun 29 15:05:08 EDT 2011


On 2011-06-29, steve+comp.lang.python at pearwood.info <steve+comp.lang.python at pearwood.info> wrote:
> I have a script running under Python 2.5 that needs to modify files in
> place. I want to do this with some level of assurance that I won't lose
> data. E.g. this is not safe:
>
> def unsafe_modify(filename):
>     fp = open(filename, 'r')
>     data = modify(fp.read())
>     fp.close()
>     fp = open(filename, 'w')  # <== original data lost here
>     fp.write(fp)
>     fp.close()  # <== new data not saved until here
>
> If something goes wrong writing the new data, I've lost the previous
> contents.
>
> I have come up with this approach:
>
> import os, tempfile
> def safe_modify(filename):
>     fp = open(filename, 'r')
>     data = modify(fp.read())
>     fp.close()
>     # Use a temporary file.
>     loc = os.path.dirname(filename)
>     fd, tmpname = tempfile.mkstemp(dir=loc, text=True)
>     # In my real code, I need a proper Python file object, 
>     # not just a file descriptor.
>     outfile = os.fdopen(fd, 'w')
>     outfile.write(data)
>     outfile.close()
>     # Move the temp file over the original.
>     os.rename(tmpname, filename)
>
> os.rename is an atomic operation, at least under Linux and Mac, so if
> the move fails, the original file should be untouched.
>
> This seems to work for me, but is this the right way to do it?

That's how Unix programs have modified files "in place" since time
immemorial.

> Is there a better/safer way?

Many programs rename the original file with a "backup" suffix (a tilde
is popular).

-- 
Grant Edwards               grant.b.edwards        Yow! It's NO USE ... I've
                                  at               gone to "CLUB MED"!!
                              gmail.com            



More information about the Python-list mailing list