5

The most naive, worst way I can think of to replace the contents of a file is:

f = open('file.txt', 'w')
f.write('stuff')
f.close()

Obviously, if that operation fails at some point before closing, you lose the contents of the original file while not necessarily finishing the new content.

So, what is the completely proper way to do this (if there is one). I imagine it's something like:

f = open('file.txt.tmp', 'w')
f.write('stuff')
f.close()
move('file.txt.tmp', 'file.txt') # dangerous line?

But is that completely atomic and safe? What are the proper commands to actually perform the move. If I have another process with an open connection to file.txt I assume that it will hold on to its pointer to the original file until is closes. What if another process tries to open up file.txt in the middle of the move?

I don't really care what version of the file my processes get as long as they get a complete, uncorrupted version.

dave mankoff
  • 17,379
  • 7
  • 50
  • 64

1 Answers1

5

Your implementation of move should use the rename function, which is atomic. Processes opening the file will see either the old or the new contents, there is no middle state. If a process already has opened the file it will keep having access to the old version after move.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • I assume rename is a system call that is available to me. Do I need to do anything like `fsync` on the file before I move it? – dave mankoff Nov 01 '12 at 22:28
  • 1
    You only need to call rename, see "man 2 rename". If you don't use C, the equivalent to rename() or move() of your language should work. Just remember that the temporary file has to be on the same filesystem for rename to work... – Joni Nov 01 '12 at 23:04