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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1348026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:01:24  来源:igfitidea点击:

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

pythonmultithreading

提问by boatcoder

Currently I have a loop that tries to find an unused filename by adding suffixes to a filename string. Once it fails to find a file, it uses the name that failed to open a new file wit that name. Problem is this code is used in a website and there could be multiple attempts to do the same thing at the same time, so a race condition exists.

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

How can I keep python from overwriting an existing file, if one is created between the time of the check and the time of the open in the other thread.

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

I can minimize the chance by randomizing the suffixes, but the chance is already minimized based on parts of the pathname. I want to eliminate that chance with a function that can be told, create this file ONLY if it doesn't exist.

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

I can use win32 functions to do this, but I want this to work cross platform because it will be hosted on linux in the end.

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

回答by RichieHindle

Use os.open()with os.O_CREATand os.O_EXCLto create the file. That will fail if the file already exists:

使用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'

Once you've created a new file, use os.fdopen()to turn the handle into a standard Python file object:

创建新文件后,使用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

Edit:From Python 3.3, the builtin open()has an xmode that means "open for exclusive creation, failing if the file already exists".

编辑:从 Python 3.3 开始,内置函数open()具有一种x模式,表示“为独占创建打开,如果文件已存在则失败”。

回答by hughdbrown

If you are concerned about a race condition, you can create a temporary fileand then rename it.

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

>>> 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

Alternatively, you can create the files using a uuidin the name. Stackoverflowitem on this.

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

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

回答by tgray

If you have an idassociated with each thread / process that tries to create the file, you could put that id in the suffix somewhere, thereby guaranteeing that no two processes can use the same file name.

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

This eliminates the race condition between the processes.

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