Python에서 실제 파일을 생성하지 않고 임시 파일 이름 생성


98

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

7
NamedTemporaryFile(아마도) 시도하고 존재한다면 재 시도함으로써 고유 한 이름을 보장합니다. 이름 만 얻는다고해서 나중에 파일을 실제로 만들 수 있다는 보장은 없습니다. 이전에 같은 이름을 사용하는 다른 사람의 경쟁 조건에 노출됩니다.
Joachim Isaksson 2014 년

5
@Joachim 사실, 여기에 경쟁 조건이 있으며 그것을 피하는 것이 좋습니다. 그러나 때로는 임시 파일 이름을 함수에 전달해야합니다 (파일 열기는 내부적으로 발생 함). 임의의 이름을 사용하면 경쟁 조건이 문제가되지 않을 가능성이 훨씬 더 높습니다. 경쟁 조건 실패의 가능성을 최소화하기 위해 좋은 임시 파일 이름을 제공해야 할 유효한 필요성이 있다고 생각합니다. 물론 실행중인 프로세스와 수행중인 작업을 기반으로 좋은 접두사와 접미사를 추가하면 충돌 가능성이 훨씬 줄어 듭니다.
PolyMesh 2015

@PolyMesh 임시 디렉토리를 만든 다음 그 안에 고정 된 이름 파일을 사용하여 경합 상태를 피할 수 있습니다. 따라서 함수는 파일이 아닌 디렉토리를 받아들이고 항상 동일한 파일을 만듭니다.
DylanYoung

tarfile을 사용하고 fileobj를 전달합니다
Wyrmwood

답변:


67

임시 파일 이름을 원한다면 내부 임시 파일 함수를 호출 할 수 있습니다 _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 

3
임시 디렉토리를 만드는 더 좋은 방법은 임시 디렉토리 temp_dir = tempfile.mkdtemp(prefix='some-prefix_')를 안전하게 만들고 절대 경로가있는 문자열을 반환하는 것입니다.
Emanuel Ey 2015 년

3
그것은 그 점을 지적하는 것이 중요합니다 next(tempfile._get_candidate_names())사용자 수준 임시 파일 인터페이스 할 수있는 이유의 것을 반드시 비 존재하지 않는 경로를 반환하지 않습니다 하지 않는 한 때까지 여러 이름 시도가 발견 :
엘리 Korvigo

1
tempfile.gettempdir()private 대신 public 을 사용할 수 있습니다 tempfile._get_default_tempdir().
flonk aug

@EmanuelEy tempfile.mkdtemp사용자를 사용할 때 임시 디렉토리와 그 내용을 삭제할 책임이 있음 을 기억하는 것이 중요 합니다.
Daniel Braun

46

이 작업을 수행하는 가장 쉽고 안전한 방법은 다음과 같습니다.

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

사용자 만 액세스 할 수있는 임시 디렉터리가 생성되므로 보안 문제는 없지만 파일이 생성되지 않으므로 해당 디렉터리에서 생성하려는 파일 이름을 선택할 수 있습니다.

편집 : Python 3에서 이제 tempfile.TemporaryDirectory()컨텍스트 관리자로 사용하여 삭제를 처리 할 수 ​​있습니다.

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

1
Daniel Braun이 위에서 언급했듯이 : tempfile.mkdtemp사용자를 사용할 때 사용자가 임시 디렉토리와 그 내용을 삭제할 책임이 있음 을 기억하는 것이 중요 합니다.
bitinerant

4
tempfile.TemporaryDirectory()컨텍스트 관리자로 사용 하는 경우 삭제됩니다.
gerrit

17

조금 늦었을지도 모르지만 문제가 있습니까?

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

37
이 코드는 실제로 이름을 얻기 위해 임시 파일을 생성하지만 질문에서는 without creating actual file in Python.
Jakub Kukul

이 질문에 대답하지 않습니다
에르베

8

tempfile.mktemp() 이 작업을 수행.

그러나 더 이상 사용되지 않습니다. 그러나 파일을 생성 하지 않으며_get_candidate_names() .

더 이상 사용되지 않는 이유는 이것을 호출하고 실제로 파일을 생성하려는 사이의 시간 차이 때문입니다. 그러나 제 경우에는 그 기회가 너무 희박하고 실패하더라도 그것은 받아 들일 것입니다. 그러나 사용 사례를 평가하는 것은 귀하에게 달려 있습니다.


1
"실패하더라도 그것은 받아 들여질 것입니다"; 경합 상태는 단순한 실패 위험이 아니라 보안 위험입니다 ( tempfile.mktemp문서 참조 ). 따라서 허용되는 것으로 간주되어서는 안됩니다.
bignose

4
@bignose 잠재적 인 보안 문제입니다. 그것은 당신이 무엇을하고 싶은지, 당신이있는 실행 환경 등에 달려 있습니다. 즉, os.path.join(tempfile.mkdtemp(), 'something')적어도 디렉토리가 생성됩니다 (그리고 당신이 소유하고 있다고 생각합니다)와 같은 일을하는 것이 더 안전 할 수 있습니다 .
Alec

5

이전 답변을 결합하여 내 솔루션은 다음과 같습니다.

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

확인 some_id당신을 위해 필요하지 않은 경우 선택.


다시 말하지만 후보 이름은 실제로 사용 가능하지 않을 수 있습니다. 정답입니다 : stackoverflow.com/a/45803022/6387880
j4hangir

1
그러나 임의의 이름을 만들어야 할 가능성이 있습니다. 그럼에도 불구하고, _get_candidate_names()존재하지 않는 경우 , 일부 세미 랜덤 문자열 생성기를 기본값으로 사용할 수 있습니다. 예를 들어 일부 uuid.
juanmirocks

4

Joachim Isaksson이 주석에서 말했듯이, 이름 만 알면 다른 프로그램이 프로그램보다 먼저 해당 이름을 사용하면 문제가 발생할 수 있습니다. 가능성은 희박하지만 불가능하지는 않습니다.

따라서이 상황에서 안전한 방법은 서명이있는 전체 GzipFile () 생성자를 사용하는 것 GzipFile( [filename[, mode[, compresslevel[, fileobj]]]])입니다. 따라서 원하는 경우 열린 fileobj와 파일 이름도 전달할 수 있습니다. 자세한 내용은 gzip 문서를 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.