如何在python中创建文件而不覆盖现有文件

boa*_*der 20 python multithreading

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

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

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

我可以使用win32函数来执行此操作,但我希望这可以跨平台工作,因为它最终将托管在linux上.

Ric*_*dle 37

使用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'
Run Code Online (Sandbox Code Playgroud)

创建新文件后,使用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
Run Code Online (Sandbox Code Playgroud)

编辑:通过Python 3.3,内建open()有一个x,意思是"开放的独家创作,没有如果文件已经存在"模式.

  • 在Linux/python 2.6上,`os.fdopen(..)`为上面的例子抛出一个带有'errno` 22的`OSError`,因为`mode`参数留给了它的默认值(`'r'`).`f = os.fdopen(fd,"w")`然而有效. (7认同)

hug*_*own 7

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

>>> 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
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用名称中的uuid创建文件.Stackoverflow项目就此而言.

>>> import uuid
>>> str(uuid.uuid1())
'64362370-93ef-11de-bf06-0023ae0b04b8'
Run Code Online (Sandbox Code Playgroud)