写入临时文件时权限被拒绝

64 投票
9 回答
72130 浏览
提问于 2025-04-18 03:41

我正在尝试在Windows操作系统上使用Python创建并写入一个临时文件。我使用了Python的一个模块tempfile来创建这个临时文件。

但是,当我试图写入这个临时文件时,出现了一个错误Permission Denied(权限被拒绝)。难道我不能写入临时文件吗?我是不是做错了什么?如果我想创建并写入一个临时文件,在Python中应该怎么做呢?我想在临时目录中创建一个临时文件,以便出于安全考虑,而不是在本地(也就是.exe文件执行的目录)创建。

IOError: [Errno 13] Permission denied: 'c:\\users\\blah~1\\appdata\\local\\temp\\tmpiwz8qw'

temp = tempfile.NamedTemporaryFile().name
f = open(temp, 'w') # error occurs on this line

9 个回答

2

tempfile.NamedTemporaryFile() :

这个函数会为你创建并打开一个临时文件。

f = open(temp, 'w') :

你又想打开一个已经打开的文件,所以你会遇到“权限被拒绝”的错误。

如果你真的想再次打开这个文件,你需要先把它关闭,操作大概是这样的-

temp= tempfile.NamedTemporaryFile()
temp.close()
f = open(temp.name, 'w')
5

下面这个自定义的命名临时文件的实现,是基于Erik Aronesty的原始回答进行扩展的:

import os
import tempfile


class CustomNamedTemporaryFile:
    """
    This custom implementation is needed because of the following limitation of tempfile.NamedTemporaryFile:

    > Whether the name can be used to open the file a second time, while the named temporary file is still open,
    > varies across platforms (it can be so used on Unix; it cannot on Windows NT or later).
    """
    def __init__(self, mode='wb', delete=True):
        self._mode = mode
        self._delete = delete

    def __enter__(self):
        # Generate a random temporary file name
        file_name = os.path.join(tempfile.gettempdir(), os.urandom(24).hex())
        # Ensure the file is created
        open(file_name, "x").close()
        # Open the file in the given mode
        self._tempFile = open(file_name, self._mode)
        return self._tempFile

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._tempFile.close()
        if self._delete:
            os.remove(self._tempFile.name)
11

可以考虑使用 os.path.join(tempfile.gettempdir(), os.urandom(24).hex()) 这个方法。这个方法很可靠,适用于不同的操作系统,唯一需要注意的是,它在FAT格式的磁盘上可能不太好用。

NamedTemporaryFile 有一些问题,其中一个比较严重的是,它可能因为权限错误而无法创建文件,甚至可能无法检测到这个权限错误,然后就会无限循环,导致你的程序和文件系统都卡住。

43

使用下面的删除参数:

tmpf = NamedTemporaryFile(delete=False)

但是,一旦你用完这个临时文件,你需要手动删除它。

tmpf.close()
os.unlink(tmpf.name)

关于这个问题的参考链接: https://github.com/bravoserver/bravo/issues/111

祝好,

Vidyesh

85

NamedTemporaryFile 实际上是为你 创建并打开 文件的,所以你不需要再去打开它来写入内容。

实际上,Python 的文档 中提到:

在命名临时文件仍然打开的情况下,是否可以用这个名字再次打开文件,因平台而异(在 Unix 系统上可以;在 Windows NT 或更高版本上则不可以)。

这就是你遇到权限错误的原因。你可能想要的代码类似于:

f = tempfile.NamedTemporaryFile(mode='w') # open file
temp = f.name                             # get name (if needed)

撰写回答