39

I am attempting to create and write to a temporary file on Windows OS using Python. I have used the Python module tempfile to create a temporary file.

But when I go to write that temporary file I get an error Permission Denied. Am I not allowed to write to temporary files?! Am I doing something wrong? If I want to create and write to a temporary file how should should I do it in Python? I want to create a temporary file in the temp directory for security purposes and not locally (in the dir the .exe is executing).

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
Mack
  • 393
  • 1
  • 4
  • 7

6 Answers6

63

NamedTemporaryFile actually creates and opens the file for you, there's no need for you to open it again for writing.

In fact, the Python docs state:

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

That's why you're getting your permission error. What you're probably after is something like:

f = tempfile.NamedTemporaryFile(mode='w') # open file
temp = f.name                             # get name (if needed)
paxdiablo
  • 814,905
  • 225
  • 1,535
  • 1,899
  • 1
    There's a useful clarification and further info in this post http://stackoverflow.com/questions/4290716/how-to-write-bytes-to-a-file-in-python-3-without-knowing-the-encoding – Iain Hunter Apr 22 '16 at 09:22
28

Use the delete parameter as below:

tmpf = NamedTemporaryFile(delete=False)

But then you need to manually delete the temporary file once you are done with it.

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

Reference for bug: https://github.com/bravoserver/bravo/issues/111

regards, Vidyesh

Tommy
  • 944
  • 2
  • 12
  • 24
Vidyesh Ranade
  • 399
  • 3
  • 5
8

Consider using os.path.join(tempfile.gettempdir(), os.urandom(24).hex()) instead. It's reliable, cross-platform, and the only caveat is that it doesn't work on FAT partitions.

NamedTemporaryFile has a number of issues, not the least of which is that it can fail to create files because of a permission error, fail to detect the permission error, and then loop millions of times, hanging your program and your filesystem.

Erik Aronesty
  • 10,225
  • 4
  • 54
  • 36
  • Much appreciated. I use pysmb to load file from a File share server,and somefile just get empty content when using tempfile.NamedTemporaryFile(). By switching to with open(filename, 'wb') as fp. the problem is solved. – Harry Duong Mar 25 '20 at 23:46
4

The following custom implementation of named temporary file is expanded on 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)
wheleph
  • 7,527
  • 7
  • 35
  • 55
0

This issue might be more complex than many of you think. Anyway this was my solution:

  1. Make use of atexit module
def delete_files(files):
    for file in files:
        file.close()
        os.unlink(file.name)
  1. Make NamedTemporaryFile delete=False
temp_files = []
 
result_file = NamedTemporaryFile(dir=tmp_path(), suffix=".xlsx", delete=False)
self.temp_files.append(result_file)
  1. Register delete_files as a clean up function
atexit.register(delete_files, temp_files)
snakecharmerb
  • 36,887
  • 10
  • 71
  • 115
-3

Permission was denied because the file is Open during line 2 of your code.

close it with f.close() first then you can start writing on your tempfile