Last active
September 25, 2015 08:29
-
-
Save dblume/2276ca3a899b73ae72dd to your computer and use it in GitHub Desktop.
Cross-platform nearly ACID file updates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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