2010-06-02 18 views
51

Ich habe ein Python-Webformular mit zwei Optionen - Datei-Upload und textarea. Ich muss die Werte von jedem nehmen und sie an ein anderes Befehlszeilenprogramm übergeben. Ich kann den Dateinamen mit Datei-Upload-Optionen leicht weitergeben, aber ich bin nicht sicher, wie man den Wert des Textarea übergibt.Python: Wie erstelle ich einen eindeutigen Dateinamen?

denke ich, was ich tun muß, ist:

  1. generiert einen eindeutigen Dateinamen
  2. Erstellen Ihnen eine temporäre Datei mit diesem Namen im Arbeitsverzeichnis
  3. Speichern Sie die von Textfeld übergebenen Werte in die temporären Datei
  4. Führen sie das Kommandozeilenprogramm aus meinem python-Modul und geben sie den Namen der temporären Datei

Ich bin mir nicht sicher, wie man einen eindeutigen Dateinamen erzeugt. Kann mir jemand Tipps geben, wie man einen eindeutigen Dateinamen generiert? Alle Algorithmen, Vorschläge und Codezeilen werden geschätzt.

Dank für Ihr Interesse

+1

I edited Ihre Frage es klarer zu versuchen und zu machen. Lass es mich wissen, wenn ich etwas falsch interpretiere! – culix

Antwort

82

ich Ihre Frage nicht ganz klar war, dachte, aber wenn alles, was Sie brauchen, ist eine eindeutige Dateinamen ...

import uuid 

unique_filename = str(uuid.uuid4()) 
+0

Sollte ich meine Frage noch verständlicher bearbeiten? – MysticCodes

+0

Tut mir leid, ich arbeite auf Windows-Plattform, so weiß nicht, wie Subprozess zu behandeln – MysticCodes

+0

Uuid scheint eine lange eindeutige Zeichenfolge zu erstellen. Ich denke nicht, dass es besser ist, Dateinamen mit langer Zeichenfolge und UUID() darin zu haben. – MysticCodes

41

Wenn Sie temporäre Dateien machen wollen In Python gibt es ein Modul namens tempfile in Pythons Standardbibliotheken. Wenn Sie andere Programme zum Ausführen der Datei starten möchten, verwenden Sie tempfile.mkstemp() zum Erstellen von Dateien und os.fdopen() zum Zugreifen auf die Dateideskriptoren, die mkstemp() zur Verfügung stellt.

Übrigens sagen Sie, dass Sie Befehle von einem Python-Programm ausführen? Sie sollten fast sicher das Modul subprocess verwenden.

So können Sie ganz fröhlich Code schreiben, der wie folgt aussieht:

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) 

Rennen, dass Sie sollten feststellen, dass der cat Befehl funktionierte sehr gut, aber die temporäre Datei wurde im finally Block gelöscht. Sei dir bewusst, dass du hast, um die temporäre Datei zu löschen, die mkstemp() selbst zurückgibt - die Bibliothek hat keine Möglichkeit zu wissen, wann du damit fertig bist!

(Edit: Ich hatte angenommen, dass NamedTemporaryFile tat genau das, was Sie wollen, aber das ist vielleicht nicht so bequem - die Datei wird sofort gelöscht, wenn das temporäre Dateiobjekt geschlossen wird und andere Prozesse die Datei vor Ihnen öffnen Ich habe geschlossen, es wird nicht auf einigen Plattformen, vor allem Windows funktionieren. Sorry, scheitern meinerseits.)

+0

mit ** NamedTemporaryFile ** ist wahrscheinlich, was sie wollen (es sei denn sie wollen es auf dem Server bleiben, und dann sie können "tempfile.NamedTemporaryFile (delete = False)" verwenden) –

+0

Kann ich diesen temporären Dateinamen auch eindeutig machen? So kann ich es später speichern, wenn Subprozess mit eindeutigen Namen abgeschlossen ist – MysticCodes

+0

@Terence Honles: Ich hatte ursprünglich tempfile.NamedTemporaryFile() vorgeschlagen, aber Sie können nicht wirklich verwenden, um temporäre Dateien, die andere Prozesse auf Windows zugreifen können. NamedTemporaryFile (delete = False) ist allerdings * cleaner *. @ user343934: Tempdatei.mkstemp() garantiert Ihnen bei jedem Aufruf einen eindeutigen Namen - er generiert die Namen nach dem Zufallsprinzip und verwendet die Betriebssystemfunktionen (O_EXCL, falls Sie sich fragen), um Kollisionen zu vermeiden. –

2

Ich stieß auf diese Frage, und ich werde meine Lösung für diejenigen hinzufügen, die nach etwas ähnlichem suchen. Mein Ansatz war nur einen zufälligen Dateinamen von ascii Zeichen zu machen. Es wird mit einer guten Wahrscheinlichkeit einzigartig sein.

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

Die offensichtliche Antwort für die Frage hatte mit dem UUID-Paket zu tun. Allerdings hat mein Zielserver Python 2.4, kein Uuid-Paket und das Upgrade wurde vom Servereigner aufgrund älterer Softwareinkompatibilitäten nicht autorisiert, daher funktioniert diese Antwort für mich. –

+1

Ich mag besonders diese Antwort: kann leicht an Projektspezifikationen angepasst werden. – swdev

+0

1) Es gibt keinen Grund, Rekursion hier zu verwenden, besonders unbegrenzt. 2) Zwischen dem Zeitpunkt, zu dem 'path.exists()' '' False 'zurückgibt, und der Zeit, zu der ein Konsument die Datei tatsächlich öffnet, besteht eine Race-Bedingung. –

8

Vielleicht brauchen Sie eine einzigartige temporäre Datei?

import tempfile 

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

print f.name 
f.close() 

Datei ist geöffnet. delete=False bedeutet, lösche Datei nicht nach dem Schließen.

+0

Das ist großartig, wenn Sie den Namen der Datei nicht kontrollieren müssen. – hiwaylon

+1

Es sollte tmpfile.NamedTemporaryFile nicht nur NamedTemporaryFile sein. – user1993015

2

Dies kann mit der einzigartigen Funktion in ufp.path Modul durchgeführt werden.

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

Wenn der aktuelle Pfad existiert 'test.ext' Datei. ufp.path.unique Funktion gibt './test (d1) .ext' zurück.

siehe Beispiel: Generate unique path at filepath or dirpath [Python]

+2

ufp ist Teil von Drupal? kein Standardmodul – endolith

2

Sie die datetime Modul verwenden können

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

Beachten Sie, dass: ich replace verwende, da die Doppelpunkte sind in Dateinamen in vielen Betriebssystemen nicht erlaubt.

Das ist es, das wird Ihnen jedes Mal einen eindeutigen Dateinamen geben.

6

Das uuid Modul wäre eine gute Wahl sein, ziehe ich uuid.uuid4().hex als zufälligen Dateinamen zu verwenden, da es einen Hex-String ohne Bindestriche zurück.

import uuid 
filename = uuid.uuid4().hex 

Die Ausgänge sollten dies mag:

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