如何创建文件并在已存在时抛出异常

7
在我的程序中,如果文件当前不存在,则许多进程都可以尝试创建该文件。现在我想确保只有一个进程能够创建该文件,而其余进程如果文件已被创建则会得到一个异常(一种进程安全和线程安全的open()实现)。我该如何在Python中实现这一点。
仅为明确起见,我希望的是,如果文件不存在,则创建该文件。但如果它已经存在,则抛出异常。并且所有这些操作都应该是原子性的。
2个回答

10

在Python 2.x中:

import os

fd = os.open('filename', os.O_CREAT|os.O_EXCL)
with os.fdopen(fd, 'w') as f:
    ....

在Python 3.3+版本中:

with open('filename', 'x') as f:
    ....

@naxa,Python 3.3+的文档open(..., 'x')没有任何availability信息;这通常意味着它支持所有平台。而Python 2.x的文档os.fdopen则提到了可用性:Unix、Windows。 - falsetru
1
根据文档:open()标志常量:以下常量是open()函数的flags参数的选项。它们可以使用按位OR运算符|组合。其中一些在所有平台上都不可用。有关其可用性和用法的描述,请参阅Unix上的open(2)手册页面或Windows上的MSDN。 - falsetru
哦,我忽略了有关打开标志的msdn文档链接。阅读不够仔细。感谢您指出这一点!我将删除早期的评论,因为您的评论实际上更加有用。 - n611x007

4

如果您使用的是类Unix系统,请按以下方式打开文件:

f = os.fdopen(os.open(filename, os.O_CREAT | os.O_WRONLY | os.O_EXCL), 'w')
< p > os.open 的标志 O_EXCL 确保文件只有在不存在时才会创建(和打开),否则将引发一个 OSError 异常。检查文件是否存在和创建将原子地执行,因此您可以有多个线程或进程争夺创建文件,仅有一个将成功。

这两个常量也应该在Windows上可用 - Ignacio Vazquez-Abrams
1
常量可能是可用的,但我不敢声称原子性的实现方式没有经过一些研究就是相同的。 - user4815162342
我认为我所要求的是,如果文件不存在,则打开它,但如果它已经存在(已被另一个进程创建),则抛出异常。看起来这段代码将在文件不存在时抛出异常,并在文件存在时通过。 - Adobri
@Adobri 这正好做了你要求的事情,但附带的测试结果是相反的。 - user4815162342

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接