beschädigte .txt Datei try/except

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
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

Habe folgendes Problem: Sagen wir ich habe eine Liste von .txt Dateien und eine davon ist beschädigt. Nun möchte ich, dass er die beschädigte Datei nicht anrührt und für diese auch keinen Ordner anlegt (Zeile 11). Das Programm soll aber mit den funktionierenden Dateien weitermachen.
Mit pass und continue lässt er die bschädigte Datei unangetastet aber er erstellt mir immernoch aus ihr einen Ordner. Weiß jemand Rat? Kann ich den os.mkdir Arbeitsschritt vorübergehend abschalten?

Code: Alles auswählen

import os, glob, shutil

def main():

 while True:
    try:
        filenames = glob.glob('F:/Test/*.txt')
        for filename in filenames:

            target = os.path.basename(filename)
            os.mkdir(target)
            shutil.move(filename, target)

            dosomething()
            
    except:
        print 'dosomething failed: ',filename
        pass
        continue


if __name__ == '__main__':
    main()

Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Wie erkennst du denn ob eine Datei beschädigt ist?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

Hab ein anderes Dateiformat eigentlich (.asc), wollte aber niemand damit verwirren. Sagen wir ich weiß , dass eine Datei beschädigt ist;) Wie gehe ich weiter vor?
BlackJack

@MarcNAV: Dann erstellst Du kein Verzeichnis dafür und verarbeitest sie nicht. Ist doch ganz einfach und offensichtlich. :-)
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

naja wenn sie beschädigten Dateien eine andere Endung haben könntest du ja nach der Endung abfragen und dadurch os.mkdir überspringen

in etwa so:

Code: Alles auswählen

if not filename.endswith('.asc'):
    target = os.path.basename(filename)
    os.mkdir(target)
    shutil.move(filename, target)
ungetestet!
BlackJack

@TryToLearn: Das nur Dateienamen mit einer bestimmten Endung in der Schleife verarbeitet werden, wird ja schon durch das `glob()` sichergestellt.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Wie wärs damit:

Code: Alles auswählen

import os, glob, shutil

def isOK(filename):
    """@todo: implement"""
    return True
 
filenames = glob.glob('F:/Test/*.txt')
for filename in filenames:
    if not isOK(filename):
        continue
    try:
        target = os.path.basename(filename)
        os.mkdir(target)
        shutil.move(filename, target)
        dosomething()
    except:
        print 'dosomething failed: ',filename
Die Funktion isOK musst Du halt noch implementieren und die Fehlerbehandlung würde ich in die innere Schleife tun.

Die "while True" Schleife und die Funktion main blähen Deinen Beispielcode nur unnötig auf.
a fool with a tool is still a fool, www.magben.de, YouTube
BlackJack

@MagBen: Die `main()`-Funktion bläht nicht unnötig auf. So ziemlich jedes nichttriviale Programm wird auf Funktionen aufgeteilt und spätestens dann möchte man die Namensräume ordentlich trennen damit Funktionen nicht einfach so absichtlich oder aus versehen auf globalem Zustand operieren.

Edit: Und dartrym frage ja schon woran man erkennt das die Datei kaputt ist. Die Vermutung liegt nahe, dass das erst in `do_something()` auffällt.
TryToLearn
User
Beiträge: 39
Registriert: Freitag 6. Juni 2014, 13:44

@BlackJack: oh richtig mein Fehler :D
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

BlackJack hat geschrieben:So ziemlich jedes nichttriviale Programm wird auf Funktionen aufgeteilt
und auch viele wenig-zeilige Beispiel-Code-Schnipsel.
a fool with a tool is still a fool, www.magben.de, YouTube
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

@BlackJack: Ja genau. Das die Datei beschädigt ist merke ich erst in dosomething(). Aber auch wenn die Datei beschädigt ist, kann Python aus der String-Dateibezeichnung einen neuen Ordner erstellen. Genau das will ich eben vermeiden.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Du könntest entweder dosomething() vor dem Erstellen des Verzeichnisses und dem Verschieben der Datei aufrufen oder in der Fehlerbehandlung die Datei zurückschieben und das Verzeichnis wieder löschen.
a fool with a tool is still a fool, www.magben.de, YouTube
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

@MagBen: Dosomething() vor dem Ordner erstellen funktioniert leider nich. Letzteres hab ich auch überlegt und werd ich wohl mal probieren
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@MarcNAV: ganz offensichtlich landest du in einem Zirkel. Um zu wissen, ob du den Ordner anlegen sollst, musst du wissen, dass die Datei nicht defekt ist. Ob die Datei defekt ist, weißt du erst, wenn du dosomething() aufgerufen hast. Bevor du dosomething() aufrufen kannst, muss zuerst der Ordner existieren.

Ich würde das Anlegen des Ordners in dosomething() erledigen, an einer Stelle, an der du sicher weißt, dass die Datei nicht defekt ist.
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Unter der Annahme, dass do_something eine Blackbox ist und die Datei unbedingt im Verzeichnis target erwartet, kann man immer eine setup-work-commit/rollback-Struktur aufbauen, die die einzelnen Aufgaben sauber trennt:

Code: Alles auswählen

def process_file(filename):
    # setup
    target = os.path.basename(filename)
    os.mkdir(target)
    shutil.copy(filename, target)
    try:
        # work
        dosomething(target)
    except FileFormatError:
        # roll back
        shutil.rmtree(target)
    else:
        # commit
        os.remove(filename)
Ob das in diesem Fall die einfachste Lösung ist, hängt halt ganz stark davon ab, was dosomething macht.
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

Irgenwie komm ich nicht aus dem Zirkel:D Auch die Idee von Sirius3 ist gut aber führt zu einer Exception. Habs jetzt einfach so gelöst, dass er zwar einen Ordner aus der fehlerhaften Datei erzeugt, aber mit ###Error vermerkt.
hab einfach in Except os.rename(target,target + "###Error") hinzugefügt.

Danke an alle
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

MarcNAV hat geschrieben:Irgenwie komm ich nicht aus dem Zirkel:D Auch die Idee von Sirius3 ist gut aber führt zu einer Exception.
Wenn du uns die Exception nicht verrätst und deinen aktuellen Code für dich behältst, dann können wir dir schlecht helfen.

Der Code von Sirius zeigt eigentlich schon recht gut wie es geht. Er muss lediglich an die zu erwartenden Ausnahmen angepasst werden.
Das Leben ist wie ein Tennisball.
MarcNAV
User
Beiträge: 52
Registriert: Freitag 16. Mai 2014, 11:39

das dosomething() ist bestimmt 100 Zeilen Codegeschwafel, das wollte ich euch ersparen.
Mir reicht die Lösung aber so. Danke euch;)
Antworten