Dateiname automatisch ändern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

ich erstelle ine .pdf mit:

Code: Alles auswählen

def Output():
    output = PdfFileWriter()  
    with nested(open("temp.pdf", "wb")) as ( temp_file):
    #hier steht mehr           
    # finally, write "output" to temp.pdf
    output.write(temp_file)
    temp_file.close()
    os.startfile('temp.pdf')
jetzt möchte ich, dass wenn temp.pdf schon geöffnet (oder anderweitig benutzt) ist, die neu erstellte Datei z.B. temp#1.pdf benannt wirt und die nächste temp#2.pdf usw.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Hallo mathi!

Hast du dir schon das tempfile Modul angesehen? Vielleicht kannst du dir dessen Funktionalität zu nutze machen.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Zu deinem Code mal allgemein:
Mit dem Kontextmanager brauchst du kein ``close`` mehr zu machen (einfach das, was danach kommt eins ausrücken) .
``nested`` ist auch unnötig bei 1 Datei, das geht auch ohne.
(Bei deiner Einrückung ist noch was schief gegangen beim Posten)
Denke außerdem an die PEP8, Funktionsnamen sollte man genauso wie Variablenname klein_mit_unterstrich schreiben.

Zu deinem Problem:
Du speicherst dir einfach die aktuelle Zahl der erstellten Dateien in einer Variablen und inkrementierst diese bei jedem Aufruf (oder alternativ ``itertools.count``). Und dann fügst diese Variable mit Stringformatierung in deinen Dateinamen ein.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

ice2k3 hat geschrieben:Zu deinem Code mal allgemein:
Mit dem Kontextmanager brauchst du kein ``close`` mehr zu machen (einfach das, was danach kommt eins ausrücken) .
``nested`` ist auch unnötig bei 1 Datei, das geht auch ohne.
(Bei deiner Einrückung ist noch was schief gegangen beim Posten)
Denke außerdem an die PEP8, Funktionsnamen sollte man genauso wie Variablenname klein_mit_unterstrich schreiben.

Zu deinem Problem:
Du speicherst dir einfach die aktuelle Zahl der erstellten Dateien in einer Variablen und inkrementierst diese bei jedem Aufruf (oder alternativ ``itertools.count``). Und dann fügst diese Variable mit Stringformatierung in deinen Dateinamen ein.

''close'' brauch ich nicht, stimmt danke,
''nested'' brauch ich, ich habe das Beispiel gekürzt der Übersicht wegen, ich habe mehr Dateien (trotzdem danke)

das mit der variablen probier ich mal, vielen Dank,
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

ich hab's jetzt folgendermaßen gelöst,
das dumme ist nur, ich muß delete=False anfügen, sonst ist das file leer. Ich erkaufe mir das mit einem nicht gelöschten .pdf im temp Ordner. Kann mir da jemand helfen??

Code: Alles auswählen

def output():
    from tempfile import NamedTemporaryFile
    output = PdfFileWriter()  
    with nested(open("tmp.pdf", "rb"),open("GraphFiles\\Rahmen.pdf", "rb")) as (tmp_file, rahmen_file):
        input1 = PdfFileReader(rahmen_file)
        input2 = PdfFileReader(tmp_file)
        
        output.addPage(input1.getPage(0))
        page0 = input1.getPage(0)
        watermark = input2
        page0.mergePage(watermark.getPage(0))
        
        temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False)
        output.write(temp_file)
        os.startfile(temp_file.name)
        temp_file.close()
edit:

ich habe mir überlegt, dass ich temp.pdf mit

Code: Alles auswählen

dir = os.getcwd()
erstelle, dann müßte ich nur noch einen wx.EVT_CLOSE einbinden.

doch wie lösche ich NamedTemporaryFile (z.B.
tempzfoxzv.pdf
) unter Windows?? mit

Code: Alles auswählen

		if os.path.exists("temp*.pdf"):
			os.remove("temp*.pdf") 
gehts ja nun nicht...


edit2:
meine Lösung ist jetzt erstmal:

Code: Alles auswählen

	def OnClose(self, event): 	
		p1=glob.glob('temp*.pdf')
		for i in p1:
			os.remove( i)
aber das kann's doch nicht sein?? Ich erstelle tempfiles und muß sie erst noch löschen??
BlackJack

@mathi: So eine Datei löschst Du wie jede andere auch: Über ihren Namen.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Zum einen kommst du mit ``temp_file.name`` an den Dateinamen. Zum anderen ist mir nicht klar, weshalb ``delete=True`` nicht funktionieren sollte?
BlackJack

@ice2k3: Weil die Datei dann beim Schliessen automatisch gelöscht wird. Das heisst bevor die externe Anwendung zum anschauen des PDFs gestartet wird.

Sie vorm Schliessen an die externe Anwendung zu übergeben geht nicht, weil Windows sich dann beschwert, dass auf die Datei schon von einer Anwendung zugegriffen wird. Windows halt…
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

BlackJack hat geschrieben:@ice2k3: Weil die Datei dann beim Schliessen automatisch gelöscht wird. Das heisst bevor die externe Anwendung zum anschauen des PDFs gestartet wird.

Sie vorm Schliessen an die externe Anwendung zu übergeben geht nicht, weil Windows sich dann beschwert, dass auf die Datei schon von einer Anwendung zugegriffen wird. Windows halt…
Ja klar... Hab irgendwie nur mit dem Quelltext versucht einen Zusammenhang herzustellen und hab gar nicht soweit gedacht :oops:

Hab aber ja eine Alternativlösung gepostet ;)
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

also komme ich um das löschen der Dateien nicht umhin??

ist ja egal

- ob ich alle temp_file.name die im Laufe des Programmes entstehen (können mehrere werden) in eine Liste packe und dann jede Datei der Liste lösche oder

- ob ich mit temp*.pdf lösche....

ich denke ich lasse es jetzt so, oder spricht was wichtiges dagegen?
BlackJack

@mathi: Dagegen spricht, dass Du vielleicht die temporären Dateien von anderen Programmen löschst, wenn die auf das Muster passen. Das ist nicht nett.

Vielleicht sogar Deine eigenen, wenn Du Dein Programm mehrfach startest.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

der Einwand ist berechtigt, aber ich leite alle temp Dateien nach

Code: Alles auswählen

 temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False,dir = os.getcwd())
also ins Installationsverzeichnis. Dieses wird dann praktisch als temp-Verzeichnis mißbraucht und soll nach beenden des Programmes von allen .pdf gesäubert sein....
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mathi hat geschrieben:der Einwand ist berechtigt, aber ich leite alle temp Dateien nach

Code: Alles auswählen

 temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False,dir = os.getcwd())
also ins Installationsverzeichnis. Dieses wird dann praktisch als temp-Verzeichnis mißbraucht und soll nach beenden des Programmes von allen .pdf gesäubert sein....
Eins verstehe ich nicht. In der Standardbibliothek gibt es gibt tempfile.mkstemp(). Warum verwendest du eine eigene Funktion die garantiert nicht all die potenziellen Fehlerfälle abfängt die die Funktion in der Standardbibliothek berücksichtigt? Alleine das Schreiben ins Programmverzeichnis würde auf keinem der Windows-, Linux- oder Solaris-Rechner funktionieren die gerade bei mir auf dem Schreibtisch stehen.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

/me hat geschrieben:
Eins verstehe ich nicht. In der Standardbibliothek gibt es gibt tempfile.mkstemp(). Warum verwendest du eine eigene Funktion die garantiert nicht all die potenziellen Fehlerfälle abfängt die die Funktion in der Standardbibliothek berücksichtigt? Alleine das Schreiben ins Programmverzeichnis würde auf keinem der Windows-, Linux- oder Solaris-Rechner funktionieren die gerade bei mir auf dem Schreibtisch stehen.
Mist, da hast Du recht, ich kann ja gar nicht garantieren, das die Schreibberechtigung gesetzt ist...

Aber, wenn der Benutzer das programm installieren konnte, dann ist doch die Berechtigung vorhanden oder??

edit: ich muß nochmal nachfragen... ich verstehe den Unterschied zw. tempfile.NamedTemporaryFile und tempfile.mkstemp im Bezug auf mein Problem nicht.. ich bin gezwungen das tempfile in irgendein verzeichnis zu schreiben und mit
delete=False
zu versehen. Damit haben doch beide Varianten das gleiche Problem oder??
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mathi hat geschrieben:
/me hat geschrieben:Aber, wenn der Benutzer das programm installieren konnte, dann ist doch die Berechtigung vorhanden oder??
Ich installiere Software als root und arbeite dann als normaler Benutzer. Unter Windows wird das - gerade in Firmen - häufig analog gehandhabt. Unter diesen Umständen sollte ein Schreiben ins Programmverzeichnis nicht mehr möglich sein.

Verwende im Zweifelsfall einfach tempfile.mkdtemp() um ein Verzeichnis zu erstellen und speichere alle temporären Dateien darin. Du brauchst dann am Programmende nur dieses eine Verzeichnis (mit Inhalten) zu entfernen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ungetestet:

Code: Alles auswählen

import os

def new_file(name, ext=""):
    num = ""
    while True:
        try:
            return os.fdopen(os.open(name + num + ext, os.O_CREAT + os.O_EXCL), "w")
        except:
            num = " %d" % (int(num) + 1) if num else " 1"
Mit der low-level-Funktion `os.open` zusammen mit den angegebenen Flags kann ich sicherstellen, dass ich eine Datei nur dann anlegen kann, wenn sie noch nicht existiert. Das Betriebssystem garantiert, dass dies eine atomare Operation ist. Somit kann ich sicher sein, dass nicht parallel ein anderer Prozess, der ebenfalls versucht, einen Dateinamen zu finden, den Vorgang stört. Mein Exception-Handler ist zu simpel. Kann die Datei z.B. nicht angelegt werden, weil das Verzeichnis nicht beschreibbar ist, habe ich eine Endlosschleife. Das zu fixen überlasse ich dem Leser.

Stefan
Antworten