Skip to content

Instantly share code, notes, and snippets.

@dblume
Last active September 25, 2015 08:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dblume/2276ca3a899b73ae72dd to your computer and use it in GitHub Desktop.
Save dblume/2276ca3a899b73ae72dd to your computer and use it in GitHub Desktop.
Cross-platform nearly ACID file updates
import platform
import tempfile
import ntpath
import filelock # https://github.com/dmfrey/FileLock
# It's interesting to see what's different between Windows and Linux.
# On Windows, you can't rename to an existing file, and you can't
# use os.fdatasync().
# Also see: http://blog.gocept.com/2013/07/15/reliable-file-updates-with-python/
def write_file(full_pathname, data):
try:
with filelock.FileLock(full_pathname):
with tempfile.NamedTemporaryFile(mode='w',
dir=ntpath.dirname(full_pathname),
delete=False) as f:
write_data_to_file(f, data)
# exiting this "with" flushes, but does not sync
f.flush()
if platform.system() == "Windows":
os.fsync(f.fileno()) # Slower, but cross-platform
if os.path.exists(full_pathname):
os.unlink(full_pathname) # otherwise WindowsError
else:
os.fdatasync(f.fileno()) # Faster, Unix only
tempname = f.name
os.rename(tempname, full_pathname) # Atomic on Unix, not Windows
except filelock.FileLockException as e:
do_something_with_exception(e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment