summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill McGugan <willmcgugan@gmail.com>2015-04-24 11:53:08 +0100
committerWill McGugan <willmcgugan@gmail.com>2015-04-24 11:53:08 +0100
commitdd541bc85a24f04c537358767836e781e9ac285b (patch)
treefdd823f6eb21d827225004d1788c8518b1d9bfca
parentce1d5dd3afa6661439d2ad5efbd05325720ffb30 (diff)
parent97c367eb6b47d6b03d6b560d65f6622d0f7e810e (diff)
downloadpyfilesystem-git-dd541bc85a24f04c537358767836e781e9ac285b.tar.gz
Merge branch 'master' of github.com:PyFilesystem/pyfilesystem
-rw-r--r--.gitignore12
-rw-r--r--fs/utils.py44
2 files changed, 55 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..89ad3c4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+*.orig
+*.project
+*.pyc
+*.egg
+*.egg-info
+*.db
+*.sqlite
+*.sublime-*
+/**/__*__
+.eggs
+.tox
+build/
diff --git a/fs/utils.py b/fs/utils.py
index 8fd6254..208fc61 100644
--- a/fs/utils.py
+++ b/fs/utils.py
@@ -16,8 +16,10 @@ __all__ = ['copyfile',
'isfile',
'isdir',
'find_duplicates',
- 'print_fs']
+ 'print_fs',
+ 'open_atomic_write']
+import os
import sys
import stat
import six
@@ -628,6 +630,46 @@ def print_fs(fs,
return dircount[0], filecount[0]
+class AtomicWriter(object):
+ """Context manager to perform atomic writes"""
+
+ def __init__(self, fs, path, mode='w'):
+ self.fs = fs
+ self.path = path
+ self.mode = mode
+ self.tmp_path = path + '~'
+ self._f = None
+
+ def __enter__(self):
+ self._f = self.fs.open(self.tmp_path, self.mode)
+ return self._f
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ if exc_type is None:
+ if self._f is not None:
+ if hasattr('_f', 'flush'):
+ self._f.flush()
+ if hasattr(self._f, 'fileno'):
+ os.fsync(self._f.fileno())
+ self._f.close()
+ self._f = None
+ self.fs.rename(self.tmp_path, self.path)
+ else:
+ if self._f is not None:
+ self._f.close()
+
+
+def open_atomic_write(fs, path, mode='w'):
+ """Open a file for 'atomic' writing
+
+ This returns a context manager which ensures that a file is written in its entirety or not at all.
+
+ """
+ return AtomicWriter(fs, path, mode=mode)
+
+
+
+
if __name__ == "__main__":
from fs.tempfs import TempFS
from six import b