gpt4 book ai didi

python - 线程安全和容错文件写入

转载 作者:太空狗 更新时间:2023-10-29 19:35:29 27 4
gpt4 key购买 nike

我有一个长时间运行的进程,它在一个文件中写入了很多东西。结果应该是一切或什么都不是,所以我正在写入一个临时文件并在最后将其重命名为真实名称。目前,我的代码是这样的:

filename = 'whatever'
tmpname = 'whatever' + str(time.time())

with open(tmpname, 'wb') as fp:
fp.write(stuff)
fp.write(more stuff)

if os.path.exists(filename):
os.unlink(filename)
os.rename(tmpname, filename)

我对此不满意有几个原因:

  • 如果发生异常,它不会正确清理
  • 它忽略并发问题
  • 它不可重用(我在程序的不同地方需要它)

有什么改进我的代码的建议吗?有图书馆可以帮助我吗?

最佳答案

您可以使用 Python 的 tempfile 模块为您提供一个临时文件名。它可以以线程安全的方式创建一个临时文件,而不是使用 time.time() 来创建临时文件,如果同时在多个线程中使用,它可能会返回相同的名称。

正如在对您的问题的评论中所建议的,这可以与上下文管理器的使用相结合。通过查看 Python tempfile.py 源代码,您可以了解如何实现您想要执行的操作。

下面的代码片段可能会做你想做的。它使用从 tempfile 返回的对象的一些内部结构。

  • 临时文件的创建是线程安全的。
  • 成功完成后重命名文件是原子的,至少在 Linux 上是这样。 os.path.exists()os.rename() 之间没有单独的检查,这可能会引入竞争条件。对于 Linux 上的原子重命名,源和目标必须在同一文件系统上,这就是此代码将临时文件与目标文件放在同一目录中的原因。
  • 在大多数情况下,RenamedTemporaryFile 类的行为应该类似于 NamedTemporaryFile,除非使用上下文管理器关闭它,文件会被重命名。

示例:

import tempfile
import os

class RenamedTemporaryFile(object):
"""
A temporary file object which will be renamed to the specified
path on exit.
"""
def __init__(self, final_path, **kwargs):
tmpfile_dir = kwargs.pop('dir', None)

# Put temporary file in the same directory as the location for the
# final file so that an atomic move into place can occur.

if tmpfile_dir is None:
tmpfile_dir = os.path.dirname(final_path)

self.tmpfile = tempfile.NamedTemporaryFile(dir=tmpfile_dir, **kwargs)
self.final_path = final_path

def __getattr__(self, attr):
"""
Delegate attribute access to the underlying temporary file object.
"""
return getattr(self.tmpfile, attr)

def __enter__(self):
self.tmpfile.__enter__()
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
self.tmpfile.delete = False
result = self.tmpfile.__exit__(exc_type, exc_val, exc_tb)
os.rename(self.tmpfile.name, self.final_path)
else:
result = self.tmpfile.__exit__(exc_type, exc_val, exc_tb)

return result

然后你可以像这样使用它:

with RenamedTemporaryFile('whatever') as f:
f.write('stuff')

在写入过程中,内容进入一个临时文件,退出时文件被重命名。此代码可能需要一些调整,但总体思路应该可以帮助您入门。

关于python - 线程安全和容错文件写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12003805/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com