Question

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
Was it helpful?

Solution

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)

OTHER TIPS

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

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.

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)

tempfile.NamedTemporaryFile() : It creates and opens a temporary file for you.

f = open(temp, 'w') : You are again going to open the file which is already open and that's why you are getting Permission Denied error.

If you really wants to open the file again then you first need to close it which will look something like this-

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

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)

this does work

T = tempfile.NamedTemporaryFile(delete=False)
z1 = open(T.name)
z2 = open(T.name)
z2 = open(T.name, mode='w')
...

I checked that you can read with all read descriptors, and write with all write descriptors

Tested with Windows 10, 10.0.19045 , and Python 3.11

ps: do not forget to delete the file when it is no longer needed:

os.unlink(T.name)

and remember that all file descriptors must be closed

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top