意外删除临时文件

Undesired deletion of temporaly files

我正在尝试创建一些临时文件并在循环内对它们进行一些操作。然后我将访问 all 临时文件的信息。并用这些信息做一些操作。为简单起见,我带来了以下重现我的问题的代码:

import tempfile
tmp_files = []
for i in range(40):
    tmp = tempfile.NamedTemporaryFile(suffix=".txt")
    with open(tmp.name, "w") as f:
        f.write(str(i))
    tmp_files.append(tmp.name)

string = ""
for tmp_file in tmp_files:
    with open(tmp_file, "r") as f:
        data = f.read()
    string += data
print(string)

错误:

 with open(tmp_file, "r") as f: FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpynh0kbnw.txt'

当我查看 /tmp 目录(循环中有一些 time.sleep(2))时,我看到文件已被删除,只保留了一个。为此错误。 当然,我可以处理保留带有标志 tempfile.NamedTemporaryFile(suffix=".txt", delete=False) 的所有文件。但这不是我们的想法。我想只为脚本的 运行 时间保存临时文件。我也可以用 os.remove 删除文件。但我的问题更多的是为什么会这样。因为我希望文件保留到 运行 的末尾。因为我没有在执行时关闭文件(或者我呢?)。 非常感谢。

默认情况下,NamedTemporaryFile 会在关闭时删除其文件。它有点微妙,但是循环中的 tmp = tempfile.NamedTemporaryFile(suffix=".txt") 会导致在重新分配 tmp 时删除前一个文件。一种选择是使用 delete=False 参数。或者,保持文件打开,并在写入后 seek 到开头。

NamedTemporaryFile 已经是一个文件对象 - 您可以直接写入它而无需重新打开。只要确保模式是“write plus”并且是文本模式,而不是二进制模式。将代码放在 try/finally 块中,以确保最后确实删除了文件。

import tempfile
tmp_files = []
try:
    for i in range(40):
        tmp = tempfile.NamedTemporaryFile(suffix=".txt", mode="w+")
        tmp.write(str(i))
        tmp.seek(0)
        tmp_files.append(tmp)

    string = ""
    for tmp_file in tmp_files:
        data = tmp_file.read()
        string += data
finally:
    for tmp_file in tmp_files:
        tmp_file.close()
print(string)

tdelaney 确实已经回答了您的实际问题。

我只想为您提供 NamedTemporaryFile 的替代方案。为什么不创建一个在脚本末尾删除的临时文件夹(其中包含所有文件)?


您可以使用 tempfile.TemporaryDirectory 而不是 NamedTemporaryFile。关闭后目录会被删除

下面的示例使用 with 语句,该语句在块结束时自动关闭文件句柄(请参阅 John Gordon 的评论)。

import os
import tempfile

with tempfile.TemporaryDirectory() as temp_folder:
    
    tmp_files = []

    for i in range(40):
        tmp_file = os.path.join(temp_folder, f"{i}.txt")
        with open(tmp_file, "w") as f:
            f.write(str(i))
        tmp_files.append(tmp_file)

    string = ""
    for tmp_file in tmp_files:
        with open(tmp_file, "r") as f:
            data = f.read()
        string += data

    print(string)