问题:生成临时文件名,而无需在Python中创建实际文件

stackoverflow中的编号为10501247的问题给出了如何在Python中创建临时文件的答案。
我只需要有一个临时文件名。
实际创建文件后,调用tempfile.NamedTemporaryFile()返回文件句柄。
有没有办法只获取文件名?

# Trying to get temp file path
tf = tempfile.NamedTemporaryFile()
temp_file_name = tf.name
tf.close()
# Here is my real purpose to get the temp_file_name
f = gzip.open(temp_file_name ,'wb')
...

The question, number 10501247, in stackoverflow gives answer how to create temporary file in Python.
I only need to have temporary file name in my case.
Calling tempfile.NamedTemporaryFile() returns file handle after actual file creation.
Is there way to get file name only?

# Trying to get temp file path
tf = tempfile.NamedTemporaryFile()
temp_file_name = tf.name
tf.close()
# Here is my real purpose to get the temp_file_name
f = gzip.open(temp_file_name ,'wb')
...

回答 0

如果只需要一个临时文件名,则可以调用内部tempfile函数_get_candidate_names()

import tempfile

temp_name = next(tempfile._get_candidate_names())
% e.g. px9cp65s

next再次调用,将返回另一个名称,等等。这不会给您临时文件夹的路径。要获取默认的“ tmp”目录,请使用:

defult_tmp_dir = tempfile._get_default_tempdir()
% results in: /tmp 

If you want a temp file name only you can call inner tempfile function _get_candidate_names():

import tempfile

temp_name = next(tempfile._get_candidate_names())
% e.g. px9cp65s

Calling next again, will return another name, etc. This does not give you the path to temp folder. To get default ‘tmp’ directory, use:

defult_tmp_dir = tempfile._get_default_tempdir()
% results in: /tmp 

回答 1

我认为最简单,最安全的方法是:

path = os.path.join(tempfile.mkdtemp(), 'something')

将创建一个只有您可以访问的临时目录,因此应该没有安全性问题,但是不会创建任何文件,因此您可以选择要在该目录中创建的任何文件名。

编辑:在Python 3中,您现在可以tempfile.TemporaryDirectory()用作上下文管理器来为您处理删除操作:

with tempfile.TemporaryDirectory() as tmp:
  path = os.path.join(tmp, 'something')
  # use path

I think the easiest, most secure way of doing this is something like:

path = os.path.join(tempfile.mkdtemp(), 'something')

A temporary directory is created that only you can access, so there should be no security issues, but there will be no files created in it, so you can just pick any filename you want to create in that directory.

edit: In Python 3 you can now use tempfile.TemporaryDirectory() as a context manager to handle deletion for you:

with tempfile.TemporaryDirectory() as tmp:
  path = os.path.join(tmp, 'something')
  # use path

回答 2

可能有点晚了,但是这有什么问题吗?

import tempfile
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as tmpfile:
    temp_file_name = tmpfile.name
f = gzip.open(temp_file_name ,'wb')

It may be a little late, but is there anything wrong with this?

import tempfile
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as tmpfile:
    temp_file_name = tmpfile.name
f = gzip.open(temp_file_name ,'wb')

回答 3

tempfile.mktemp() 做这个。

但是请注意,它已被弃用。但是,它不会创建文件,与使用相比,它是tempfile中的公共函数_get_candidate_names()

不建议使用它的原因是由于调用此方法与实际尝试创建文件之间存在时间间隔。但是在我看来,这样做的机会非常渺茫,即使失败了也可以接受。但是由您来评估用例。

tempfile.mktemp() do this.

But note that it’s deprecated. However it will not create the file and it is a public function in tempfile compared to using the _get_candidate_names().

The reason it’s deprecated is due to the time gap between calling this and actually trying to create the file. However in my case the chance of that is so slim and even if it would fail that would be acceptable. But it’s up to you to evaluate for your usecase.


回答 4

结合先前的答案,我的解决方案是:

def get_tempfile_name(some_id):
    return os.path.join(tempfile.gettempdir(), next(tempfile._get_candidate_names()) + "_" + some_id)

some_id如果不需要,请设置为可选。

Combining the previous answers, my solution is:

def get_tempfile_name(some_id):
    return os.path.join(tempfile.gettempdir(), next(tempfile._get_candidate_names()) + "_" + some_id)

Make some_id optional if not needed for you.


回答 5

正如Joachim Isaksson在评论中说的那样,如果您只是得到一个名字,那么如果某个其他程序在您的程序之前恰好使用了该名字,则可能会遇到问题。机会渺茫,但并非不可能。

因此,在这种情况下,安全的做法是使用具有签名的完整GzipFile()构造函数GzipFile( [filename[, mode[, compresslevel[, fileobj]]]])。因此,您可以根据需要向其传递打开的fileobj和文件名。有关详细信息,请参见gzip文档。

As Joachim Isaksson said in the comments, if you just get a name you may have problems if some other program happens to use that name before your program does. The chances are slim, but not impossible.

So the safe thing to do in this situation is to use the full GzipFile() constructor, which has the signature GzipFile( [filename[, mode[, compresslevel[, fileobj]]]]). So you can pass it the open fileobj, and a filename as well, if you like. See the gzip docs for details.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。