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