Python write in mkstemp() file
Asked Answered
A

4

27

I am creating a tmp file by using :

from tempfile import mkstemp

I am trying to write in this file :

tmp_file = mkstemp()
file = open(tmp_file, 'w')
file.write('TEST\n')

Indeed I close the file and do it proper but when I try to cat the tmp file, it stills empty..It looks basic but I don't know why it doesn't work, any explanations ?

Android answered 18/7, 2016 at 12:40 Comment(1)
Yes I do it. file.close(), I even tried to get the fd and close it using os.close(fd)Android
C
31

mkstemp() returns a tuple with a file descriptor and a path. I think the issue is that you're writing to the wrong path. (You're writing to a path like '(5, "/some/path")'.) Your code should look something like this:

from tempfile import mkstemp

fd, path = mkstemp()

# use a context manager to open the file at that path and close it again
with open(path, 'w') as f:
    f.write('TEST\n')

# close the file descriptor
os.close(fd)
Chobot answered 18/7, 2016 at 12:52 Comment(5)
Well, I tried to use both, when I do path = mkstemp(), it returns only the path of the file. And it stills create the file at the right path, that's why I think it's not the problem.Android
@SteevenBrunner I don't see how that could be. If you do path = mkstemp(); print(path), what's the output? I'm pretty sure it has to be a tuple.Chobot
@SteevenBrunner What version of Python are you using? (Perhaps older versions have a different behavior.)Chobot
My mistake, I did fd, temp_file = mkstemp() print '\n' + temp_file, I had not even noticed it. So yes you're right it returns a tuple, sorry for the waste of time :( @smarxAndroid
I tried to add a comment but it would not be formatted properly. Therefore I added it as an answer.Derivation
D
39

The answer by smarx opens the file by specifying path. It is, however, easier to specify fd instead. In that case the context manager closes the file descriptor automatically:

import os
from tempfile import mkstemp

fd, path = mkstemp()

# use a context manager to open (and close) file descriptor fd (which points to path)
with os.fdopen(fd, 'w') as f:
    f.write('TEST\n')

# This causes the file descriptor to be closed automatically
Derivation answered 1/5, 2018 at 8:53 Comment(0)
C
31

mkstemp() returns a tuple with a file descriptor and a path. I think the issue is that you're writing to the wrong path. (You're writing to a path like '(5, "/some/path")'.) Your code should look something like this:

from tempfile import mkstemp

fd, path = mkstemp()

# use a context manager to open the file at that path and close it again
with open(path, 'w') as f:
    f.write('TEST\n')

# close the file descriptor
os.close(fd)
Chobot answered 18/7, 2016 at 12:52 Comment(5)
Well, I tried to use both, when I do path = mkstemp(), it returns only the path of the file. And it stills create the file at the right path, that's why I think it's not the problem.Android
@SteevenBrunner I don't see how that could be. If you do path = mkstemp(); print(path), what's the output? I'm pretty sure it has to be a tuple.Chobot
@SteevenBrunner What version of Python are you using? (Perhaps older versions have a different behavior.)Chobot
My mistake, I did fd, temp_file = mkstemp() print '\n' + temp_file, I had not even noticed it. So yes you're right it returns a tuple, sorry for the waste of time :( @smarxAndroid
I tried to add a comment but it would not be formatted properly. Therefore I added it as an answer.Derivation
F
9

This example opens the Python file descriptor with os.fdopen to write cool stuff, then close it (at the end of the with context block). Other non-Python processes can use the file. And at the end, the file is deleted.

import os
from tempfile import mkstemp

fd, path = mkstemp(text=True)

with os.fdopen(fd, 'w') as fp:
    fp.write('cool stuff\n')

# Do something else with the file, e.g.
# os.system('cat ' + path)

# Delete the file
os.remove(path)
Flor answered 27/3, 2019 at 7:41 Comment(2)
Python3.11(I didn't test all versions) doesn't delete it. I recommend os.remove(path). See alsoVanadous
I think this code has an error. Shouldn't you say mkstemp(text=True)? the default will return a file descriptor in BINARY mode, but apparently you want TEXT modeRimple
B
3

mkstemp returns (fd, name) where fd is an os-level file descriptor ready for writing in binary mode; so all you need is to use os.write(fd, 'TEST\n'), and then os.close(fd).

No need to re-open the file using either open or os.fdopen.

jcomeau@bendergift:~$ python
Python 2.7.16 (default, Apr  6 2019, 01:42:57) 
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> from tempfile import mkstemp
>>> fd, name = mkstemp()
>>> os.write(fd, 'TEST\n')
5
>>> print(name)
/tmp/tmpfUDArK
>>> os.close(fd)
>>> 
jcomeau@bendergift:~$ cat /tmp/tmpfUDArK 
TEST

In command-line testing, of course, there is no need to use os.close, since the file is closed on exit anyway. But that is bad programming practice.

Beverleebeverley answered 8/7, 2021 at 0:28 Comment(2)
os.write() is a binary interface, while os.fdopen() allows to open in text mode, so you get correct new lines for your system. It also allows to specify encoding so writes will encode strings as desired.Kinesiology
@Kinesiology I think that os.write can be either text or binary. if you open the descriptor using mkstemp(text=True) then it will be text mode.Rimple

© 2022 - 2024 — McMap. All rights reserved.