【问题标题】:Permission Denied To Write To My Temporary File写入我的临时文件的权限被拒绝
【发布时间】:2014-06-06 09:43:46
【问题描述】:

我正在尝试使用 Python 在 Windows 操作系统上创建和写入临时文件。我已经使用 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

【问题讨论】:

    标签: python temporary-files


    【解决方案1】:

    NamedTemporaryFile实际上为你创建并打开文件,不需要你再次打开它来写。

    其实Python docs状态:

    在命名的临时文件仍处于打开状态时,该名称是否可用于第二次打开文件,因平台而异(在 Unix 上可以这样使用;在 Windows NT 或更高版本上不能强>)。

    这就是您收到权限错误的原因。您可能想要的是:

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

    【讨论】:

    【解决方案2】:

    这个问题可能比你们许多人想象的要复杂。无论如何,这是我的解决方案:

    1. 利用 atexit 模块
    def delete_files(files):
        for file in files:
            file.close()
            os.unlink(file.name)
    
    1. 制作NamedTemporaryFile delete=False
    temp_files = []
     
    result_file = NamedTemporaryFile(dir=tmp_path(), suffix=".xlsx", delete=False)
    self.temp_files.append(result_file)
    
    1. 注册delete_files为清理函数
    atexit.register(delete_files, temp_files)
    

    【讨论】:

      【解决方案3】:

      以下命名临时文件的自定义实现在the original answer by 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)
      

      【讨论】:

        【解决方案4】:

        考虑改用os.path.join(tempfile.gettempdir(), os.urandom(24).hex())。它可靠、跨平台,唯一需要注意的是它不适用于 FAT 分区。

        NamedTemporaryFile 有很多问题,其中最重要的是它可能因为权限错误而无法创建文件,无法检测到权限错误,然后循环数百万次,挂起你的程序和文件系统。

        【讨论】:

        • 非常感谢。我使用 pysmb 从文件共享服务器加载文件,当使用 tempfile.NamedTemporaryFile() 时,somefile 只是获取空内容。通过切换到 with open(filename, 'wb') as fp.问题解决了。
        【解决方案5】:

        权限被拒绝,因为文件在代码的第 2 行处于打开状态。

        先用 f.close() 关闭它,然后你就可以开始在你的临时文件上写了

        【讨论】:

          【解决方案6】:

          使用delete参数如下:

          tmpf = NamedTemporaryFile(delete=False)
          

          但是你需要在完成后手动删除临时文件。

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

          错误参考:https://github.com/bravoserver/bravo/issues/111

          问候, 视频

          【讨论】:

          • 即使使用with语句也需要手动删除吗?
          猜你喜欢
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 2015-11-24
          • 1970-01-01
          • 2017-03-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多