with open(tmpFile, 'w') as f:
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())
os.replace(tmpFile, myFile) # os.rename pre-3.3, but os.rename won't work on Windows
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:
dst.write(line)
使用两个简单的上下文管理器
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.pop('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)
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.
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")
import os import random
path = "C:\\Users\\ANTRAS\\Desktop\\NUOTRAUKA\\"
def renamefiles():
files = os.listdir(path)
i = 1
for file in files:
os.rename(os.path.join(path, file), os.path.join(path,
random.choice('ABCDEFGHIJKL') + str(i) + str(random.randrange(31,9999999,2)) + '.jpg'))
i = i+1
for x in range(30):
renamefiles()
7条答案
按热度按时间sauutmhj1#
将数据写入临时文件,当数据成功写入时,将文件重命名为正确的目标文件,例如
根据文件www.example.comhttp://docs.python.org/library/os.html#os.replace
将文件或目录
src
重命名为dst
。如果dst为非空目录,则将引发OSError
。如果dst
存在并且是文件,则在用户具有权限的情况下将以静默方式替换它。如果src
和dst
位于不同的文件系统上,则此操作可能会失败。如果成功,重命名将是原子操作(这是POSIX要求)。注:
os.fsync
步骤unhi4e5o2#
这是一个使用Python
tempfile
实现原子写入的简单代码片段。或者甚至从同一文件阅读和写入:
使用两个简单的上下文管理器
s3fp2yjn3#
因为很容易把细节搞得一团糟,我建议使用一个小型的库,库的优点是它可以处理所有这些细节,并且是社区的reviewed and improved。
一个这样的库是 * untitaker * 的
python-atomicwrites
,它甚至有适当的Windows支持:此库目前未维护。作者评论:
[...],我想这是一个弃用这个包的好时机,Python 3有os.replace和os.rename,它们对于大多数用例来说可能已经足够好了。
来自自述文件:
通过PIP安装:
pjngdqdw4#
我使用这段代码原子地替换/写入一个文件:
用法:
它基于this recipe。
wrrgggsh5#
完成后只需链接文件即可:
如果你想玩花样:
ej83mcc06#
这个页面上的答案是相当古老的,现在有图书馆为您做这件事。
特别是
safer
是一个库,旨在帮助防止程序员错误损坏文件,套接字连接,或通用流.它是相当灵活的,除其他事项外,它可以选择使用内存或临时文件,您甚至可以保留临时文件,以防失败.他们的例子正是你想要的:
它位于PyPI中,只需使用
pip install --user safer
安装即可,或者从https://github.com/rec/safer获取最新版本tquggr8v7#
用于Windows循环文件夹和重命名文件的原子解决方案。经过测试,原子自动化,您可以增加概率,以最大限度地降低风险,而不是具有相同的文件名的事件。您的字母符号组合随机库使用随机。选择方法,用于数字字符串(随机。随机。范围(50,9999999,2)。您可以根据需要更改数字范围。