繁体   English   中英

如何在不覆盖现有文件的情况下在 python 中创建文件

[英]How do I create a file in python without overwriting an existing file

目前我有一个循环,它试图通过向文件名字符串添加后缀来查找未使用的文件名。 一旦它找不到文件,它就会使用未能打开具有该名称的新文件的名称。 问题是此代码在网站中使用,并且可能会多次尝试同时执行相同的操作,因此存在竞争条件。

如果在检查时间和另一个线程中打开时间之间创建了一个文件,我如何防止 python 覆盖现有文件。

我可以通过随机化后缀来最小化机会,但是根据路径名的一部分,这个机会已经最小化了。 我想用一个可以告诉的函数来消除这个机会,只有在它不存在时才创建这个文件。

我可以使用 win32 函数来做到这一点,但我希望它能够跨平台工作,因为它最终将托管在 linux 上。

os.open()os.O_CREATos.O_EXCL来创建文件。 如果文件已经存在,那将会失败:

>>> fd = os.open("x", os.O_WRONLY | os.O_CREAT | os.O_EXCL)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 17] File exists: 'x'

创建新文件后,使用os.fdopen()将句柄转换为标准 Python 文件对象:

>>> fd = os.open("y", os.O_WRONLY | os.O_CREAT | os.O_EXCL)
>>> f = os.fdopen(fd, "w")  # f is now a standard Python file object

编辑:从 Python 3.3 开始,内置的open()有一个x模式,这意味着“为独占创建打开,如果文件已经存在则失败”。

如果您担心竞争条件,您可以创建一个临时文件,然后重命名它。

>>> import os
>>> import tempfile
>>> f = tempfile.NamedTemporaryFile(delete=False)
>>> f.name
'c:\\users\\hughdb~1\\appdata\\local\\temp\\tmpsmdl53'
>>> f.write("Hello world")
>>> f.close()
>>> os.rename(f.name, r'C:\foo.txt')
>>> if os.path.exists(r'C:\foo.txt') :
...     print 'File exists'
...
File exists

或者,您可以使用名称中的uuid创建文件。 关于此的Stackoverflow项目。

>>> import uuid
>>> str(uuid.uuid1())
'64362370-93ef-11de-bf06-0023ae0b04b8'

如果您有一个与尝试创建文件的每个线程/进程相关联的id ,您可以将该 id 放在后缀中的某个位置,从而保证没有两个进程可以使用相同的文件名。

这消除了进程之间的竞争条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM