primefaces写入到Python文件

我正在使用Python在单个操作中将文本块写入文件:

open(file, 'w').write(text) 

如果脚本中断,所以文件写入不完成我想没有文件,而不是部分完整的文件。 可以这样做吗?

将数据写入临时文件,当数据成功写入时,将文件重命名为正确的目标文件,例如

 f = open(tmpFile, 'w') f.write(text) # make sure that all data is on disk # see http://stackoverflow.com/questions/7433057/is-rename-without-fsync-safe f.flush() os.fsync(f.fileno()) f.close() os.rename(tmpFile, myFile) 

根据doc http://docs.python.org/library/os.html#os.rename

如果成功,重命名将是一个primefaces操作(这是一个POSIX的要求)。 在Windows上,如果dst已经存在,即使它是一个文件,也会引发OSError; 当dst命名现有文件时,可能无法实现primefaces重命名

如果src和dst位于不同的文件系统上,操作可能会失败。

注意:

  • 如果src和dest位置不在同一个文件系统上,它可能不是primefaces操作

  • 如果在断电,系统崩溃等情况下,性能/响应比数据完整性更重要,则可以跳过os.fsync步骤

一个使用Python tempfile实现primefaces写入的简单片段。

 with open_atomic('test.txt', 'w') as f: f.write("huzza") 

甚至读写同一个文件:

 with open('test.txt', 'r') as src: with open_atomic('test.txt', 'w') as dst: for line in src: f.write(line) 

用两个简单的上下文pipe理器

 import os import tempfile as tmp from contextlib import contextmanager @contextmanager def tempfile(suffix='', dir=None): """ Context for temporary file. Will find a free temporary filename upon entering and will try to delete the file on leaving, even in case of an exception. Parameters ---------- suffix : string optional file suffix dir : string optional directory to save temporary file in """ tf = tmp.NamedTemporaryFile(delete=False, suffix=suffix, dir=dir) tf.file.close() try: yield tf.name finally: try: os.remove(tf.name) except OSError as e: if e.errno == 2: pass else: raise @contextmanager def open_atomic(filepath, *args, **kwargs): """ Open temporary file object that atomically moves to destination upon exiting. Allows reading and writing to and from the same filename. The file will not be moved to destination in case of an exception. Parameters ---------- filepath : string the file path to be opened fsync : bool whether to force write the file to disk *args : mixed Any valid arguments for :code:`open` **kwargs : mixed Any valid keyword arguments for :code:`open` """ fsync = kwargs.get('fsync', False) with tempfile(dir=os.path.dirname(os.path.abspath(filepath))) as tmppath: with open(tmppath, *args, **kwargs) as file: try: yield file finally: if fsync: file.flush() os.fsync(file.fileno()) os.rename(tmppath, filepath) 

有一个简单的AtomicFile助手: https : //github.com/sashka/atomicfile

我使用这个代码来自动replace/写入一个文件:

 import os from contextlib import contextmanager @contextmanager def atomic_write(filepath, binary=False, fsync=False): """ Writeable file object that atomically updates a file (using a temporary file). :param filepath: the file path to be opened :param binary: whether to open the file in a binary mode instead of textual :param fsync: whether to force write the file to disk """ tmppath = filepath + '~' while os.path.isfile(tmppath): tmppath += '~' try: with open(tmppath, 'wb' if binary else 'w') as file: yield file if fsync: file.flush() os.fsync(file.fileno()) os.rename(tmppath, filepath) finally: try: os.remove(tmppath) except (IOError, OSError): pass 

用法:

 with atomic_write('path/to/file') as f: f.write("allons-y!\n") 

这是基于这个配方 。

由于搞砸细节非常容易,我build议使用一个小型库。 图书馆的优势在于它能够处理所有这些细节,并且正在由一个社区进行审查和改进 。

一个这样的库是由untitaker python-atomicwrites atomicwrites ,甚至有适当的Windows支持:

从自述文件:

 from atomicwrites import atomic_write with atomic_write('foo.txt', overwrite=True) as f: f.write('Hello world.') # "foo.txt" doesn't exist yet. # Now it does.