Python : 고유 한 파일 이름을 만드는 방법은 무엇입니까?


95

파일 업로드텍스트 영역의 두 가지 옵션이있는 파이썬 웹 양식이 있습니다 . 각각의 값을 가져 와서 다른 명령 줄 프로그램에 전달해야합니다. 파일 업로드 옵션으로 파일 이름을 쉽게 전달할 수 있지만 텍스트 영역의 값을 전달하는 방법을 잘 모르겠습니다.

제가해야 할 일은 다음과 같습니다.

  1. 고유 한 파일 이름 생성
  2. 작업 디렉토리에 해당 이름으로 임시 파일을 만듭니다.
  3. 텍스트 영역에서 전달 된 값을 임시 파일에 저장
  4. 내 파이썬 모듈 내부에서 명령 줄 프로그램을 실행하고 임시 파일의 이름을 전달합니다.

고유 한 파일 이름을 생성하는 방법을 잘 모르겠습니다. 아무도 고유 파일 이름을 생성하는 방법에 대한 몇 가지 팁을 줄 수 있습니까? 모든 알고리즘, 제안 및 코드 줄에 감사드립니다.

여러분의 관심에 감사드립니다


1
더 명확하게하기 위해 질문을 수정했습니다. 내가 잘못 해석하면 알려주세요!
culix

답변:


147

질문이 명확하지 않다고 생각했지만 고유 한 파일 이름 만 있으면됩니다.

import uuid

unique_filename = str(uuid.uuid4())

죄송합니다. 저는 Windows 플랫폼에서 작업하고 있으므로 하위 프로세스를 처리하는 방법을 모릅니다
MysticCodes

uuid는 길고 고유 한 문자열을 만드는 것 같습니다. 긴 문자열과 UUID, ()가있는 파일 이름을 갖는 것이 더 낫다고 생각하지 않습니다.
MysticCodes 2010-06-03

6
uuid.uuid4().hex더 나은 선택이 될 것이라고 생각 합니다 . 자세한 내용은 여기를 참조 하십시오 .
Gray Li

4
@ToloPalmer : 생성 된 UUID가 기존 값과 충돌하는 것보다 컴퓨터의 CPU에 잘못된 파일을로드하는 처리 오류가있을 가능성이 큽니다. UUID는 모든 계산이 순수한 수학이 아니라는 것을 이해하는 컴퓨팅 모델에서 고유 한 이름을 생성합니다.
GManNickG

2
나의 무지 된 의견 용서 ... 사실, 그래서 좋은 선택하지 고유하지만 충돌 가능성은 매우 낮)
톨로 팔머

51

Python에서 임시 파일을 만들고 싶다면 Python의 표준 라이브러리에 tempfile 이라는 모듈이 있습니다. 다른 프로그램을 실행하여 파일에서 작동하려면 tempfile.mkstemp ()를 사용하여 파일을 만들고 os.fdopen ()을 사용하여 mkstemp ()가 제공하는 파일 설명자에 액세스합니다.

덧붙여서, 파이썬 프로그램에서 명령을 실행하고 있다고 말씀하십니까? 거의 확실하게 subprocess 모듈을 사용해야 합니다.

따라서 다음과 같은 코드를 매우 즐겁게 작성할 수 있습니다.

import subprocess
import tempfile
import os

(fd, filename) = tempfile.mkstemp()
try:
    tfile = os.fdopen(fd, "w")
    tfile.write("Hello, world!\n")
    tfile.close()
    subprocess.Popen(["/bin/cat", filename]).wait()        
finally:
    os.remove(filename)

그것을 실행하면 cat명령이 완벽하게 잘 작동하지만 임시 파일이 finally블록 에서 삭제 되었음을 알 수 있습니다. 당신이 알고 수 있는 라이브러리가 당신이 그것을 완료하면 알 수있는 방법이 있습니다 -은 mkstemp ()가 자신을 반환하는 임시 파일을 삭제!

(편집 : NamedTemporaryFile이 정확히 원하는 작업을 수행했다고 가정했지만 그렇게 편리하지 않을 수 있습니다. 임시 파일 개체가 닫히면 파일이 즉시 삭제되고 파일을 닫기 전에 다른 프로세스가 파일을 열도록합니다. 일부 플랫폼, 특히 Windows에서는 작동하지 않습니다. 죄송합니다. 실패했습니다.)


사용 NamedTemporaryFile는 그들이 원하는 것을 아마도 (그들이 서버에 있고 싶어하지 않는 한, 그리고 그들은 ") (삭제 = 거짓 tempfile.NamedTemporaryFile"를 사용할 수 있습니다)
테렌스 Honles

임시 파일 이름도 고유하게 만들 수 있습니까? 내가 그것을 저장할 수 있도록 하위 프로세스는 고유 한 이름으로 완료된 후에 때
MysticCodes

@Terence Honles : 원래 tempfile.NamedTemporaryFile ()을 제안했지만 다른 프로세스가 Windows에서 액세스 할 수있는 임시 파일을 만드는 데 실제로 사용할 수는 없습니다. NamedTemporaryFile (delete = False)는 확실히 더 깨끗 합니다. @ user343934 : tempfile.mkstemp ()는 호출 될 때마다 고유 한 이름을 제공합니다. 이름을 무작위로 생성하고 충돌을 피하기 위해 OS 기능 (O_EXCL)을 사용합니다.
Richard Barrell

와우 나는 그것이 창문에서 작동하지 않는다는 것을 몰랐습니다. 실패 :( ... 알아두면 좋은 것 같아요
Terence Honles

@Terence Honles : NamedTemporaryFile ()은 실제로 Windows에서 실패하지는 않지만 (내가 아는 한) 파일을 삭제하지 않고는 파일을 닫을 수 없으며 (Windows에서 파일 의미론을 이해하기 때문에) 다른 프로그램에서 열 수 없습니다. 열려있는 동안 파일. 내가 틀렸을지도 모른다; Windows에서 여러 프로세스가 파일을 공유하는 의미는 내가 마지막으로 확인한 이후로 변경되었을 수 있습니다.
Richard Barrell

32

uuid모듈은 좋은 선택이 될 것입니다, 내가 사용하는 것을 선호 uuid.uuid4().hex가 반환하기 때문에 임의의 파일 이름으로 대시없이 16 진수 문자열을 .

import uuid
filename = uuid.uuid4().hex

출력은 다음과 같아야합니다.

>>> import uuid
>>> uuid.uuid()
UUID('20818854-3564-415c-9edc-9262fbb54c82')
>>> str(uuid.uuid4())
'f705a69a-8e98-442b-bd2e-9de010132dc4'
>>> uuid.uuid4().hex
'5ad02dfb08a04d889e3aa9545985e304'  # <-- this one

1
대시의 문제는 무엇입니까?
David Lopez

15

고유 한 임시 파일이 필요한가요?

import tempfile

f = tempfile.NamedTemporaryFile(mode='w+b', delete=False)

print f.name
f.close()

f는 열린 파일입니다. delete=False닫은 후 파일을 삭제하지 않음을 의미합니다.

파일 이름을 제어해야하는 경우 문자열을받는 옵션 prefix=...suffix=...인수가 있습니다. https://docs.python.org/3/library/tempfile.html을 참조 하십시오 .


파일 이름을 제어 할 필요가없는 경우 유용합니다.
hiwaylon 2014 년

1
NamedTemporaryFile뿐만 아니라 tmpfile.NamedTemporaryFile이어야합니다.
user1993015 jul.

w+b기본값 mode입니다. 모든 tempfile기능을 사용하면 잘못된 파일 액세스 권한이라는 단점이 있습니다. tempfile문서 os.O_TMPFILE는 마스크 로 사용할 수 있지만 일반적인 파일 생성은 os.umask().
m8mble

8

datetime 모듈을 사용할 수 있습니다.

import datetime
uniq_filename = str(datetime.datetime.now().date()) + '_' + str(datetime.datetime.now().time()).replace(':', '.')

참고 : replace많은 운영 체제에서 파일 이름에 콜론이 허용되지 않기 때문에 사용 하고 있습니다.

이것이 매번 고유 한 파일 이름을 제공합니다.


2
파일 이름이 서로 바로 뒤에 생성되지 않는 한 (예 : 루프). 그렇다면 그들은 동일합니다.
skjerns

1

나는이 질문을 보았고 비슷한 것을 찾고있는 사람들을 위해 해결책을 추가 할 것입니다. 내 접근 방식은 ascii문자 에서 임의의 파일 이름을 만드는 것이 었습니다 . 그것은 좋은 확률로 독특합니다.

from random import sample
from string import digits, ascii_uppercase, ascii_lowercase
from tempfile import gettempdir
from os import path

def rand_fname(suffix, length=8):
    chars = ascii_lowercase + ascii_uppercase + digits

    fname = path.join(gettempdir(), 'tmp-'
                + ''.join(sample(chars, length)) + suffix)

    return fname if not path.exists(fname) \
                else rand_fname(suffix, length)

1
질문에 대한 분명한 대답은 uuid 패키지와 관련이 있습니다. 그러나 내 대상 서버에는 python 2.4가 있고 uuid 패키지가 없으며 레거시 소프트웨어 비 호환성으로 인해 서버 소유자가 업그레이드를 승인하지 않았 으므로이 답변이 저에게 효과적입니다.
Alberto Gaona 2014 년

1
특히이 답변이 마음에 듭니다. 프로젝트 사양에 맞게 쉽게 조정할 수 있습니다.
swdev 2015-04-29

1
1) 여기서 재귀를 사용할 이유가 없습니다. 특히 제한이 없습니다. 2) path.exists()반환 False되는 시간과 소비자가 실제로 파일을 여는 시간 사이에 경쟁 조건이 있습니다 .
Jonathon Reinhart의 2017

1

이것은 ufp.path 모듈 의 고유 기능을 사용하여 수행 할 수 있습니다 .

import ufp.path
ufp.path.unique('./test.ext')

현재 경로가 'test.ext'파일이있는 경우. ufp.path.unique 함수는 './test (d1) .ext'를 반환합니다.


6
ufp는 drupal의 일부입니까? 표준 모듈이
아님

1

존재하는 경우 고유 한 파일 경로를 만들려면 임의 패키지를 사용하여 파일에 대한 새 문자열 이름을 생성합니다. 동일한 코드를 아래에서 참조 할 수 있습니다.

import os
import random
import string

def getUniquePath(folder, filename):    
    path = os.path.join(folder, filename)
    while os.path.exists(path):
         path = path.split('.')[0] + ''.join(random.choice(string.ascii_lowercase) for i in range(10)) + '.' + path.split('.')[1]
    return path

이제이 경로를 사용하여 그에 따라 파일을 만들 수 있습니다.


1

파일 이름으로 짧은 고유 ID가 필요한 경우 try shortuuid, shortuuid 는 소문자 및 대문자와 숫자를 사용하고 l, 1, I, O 및 0과 같은 유사한 문자를 제거합니다.

>>> import shortuuid
>>> shortuuid.uuid()
'Tw8VgM47kSS5iX2m8NExNa'
>>> len(ui)
22

에 비해

>>> import uuid
>>> unique_filename = str(uuid.uuid4())
>>> len(unique_filename)
36
>>> unique_filename
'2d303ad1-79a1-4c1a-81f3-beea761b5fdf'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.