5 Stimmen

Verwaltung von unter Mac OS erstellten Dateinamen mit Nicht-ASCII-Zeichen in Windows-Umgebungen?

Ich habe mit einer großen Sammlung unbekannter Dateien zu tun und habe Python gelernt, um mir beim Filtern/Sortieren und beim sonstigen Umgang mit diesen Dateien zu helfen.

Eine Sammlung, die ich betrachte, hat eine große Anzahl von Ressourcenzweigen, und ich schrieb ein kleines Skript, um sie zu finden und zu löschen (der nächste Schritt ist, sie zu finden und zu verschieben, aber das ist für einen anderen Tag).

Ich habe in dieser Sammlung eine Reihe von Dateien gefunden, die Nicht-Ascii-Zeichen im Dateinamen haben, und das scheint die os.delete-Funktion auszulösen.

Beispiel für einen Dateinamen: ._spec com report 395 (N.B. die 3 hat einen kleinen Punkt darunter, ich kann kein Beispiel finden oder herausfinden, wie ich das Hexadezimalzeichen des Dateinamens anzeigen kann...)

Ich protokolliere alle Dateinamen, das ist, was das Protokoll für diese Datei aufzeichnet: ._spec com report 3?95

Der Fehler, den ich erhalte, ist ein Windowsfehler, da es die Datei nicht finden kann (die Zeichenfolge seine Übergabe ist nicht, was die Datei durch das Windows-Betriebssystem bekannt ist).

Ich habe auch versucht, einen Unicode-Schalter in der walk-Option `os.walk(u'.') zu verwenden, wie in diesem Beitrag beschrieben: Behandlung von Ascii-Zeichen in Python-Strings (oberste Antwort) und ich sehe den folgenden Fehler:

Traceback (most recent call last):
 File "<stdin>", line 3, in <module>
 File "c:\python27\lib\encodings\cp850.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\uf022' in position
20: character maps to <undefined>

Ich vermute also, dass die Antwort darin liegt, wie der Dateiname geparst wird, und frage mich, ob jemand in der Lage sein könnte, mich in die richtige Richtung zu weisen...

Code:

import os
import sys

rootdir = "c:\target Dir to walk"
destKeep = "Keepers.txt"
destDelete = "Deleted.txt"

matchingText = "._"
files_removed = 1
for folder, subs, files in os.walk(rootdir):  
    outfileKeep = open(destKeep,"a")
    outfileDelete = open(destDelete,"a")
    for filename in files:
        matchScore = filename.find(matchingText)
        src = os.path.join(folder, filename)
        srcNewline = src + ", " + str(filename) + "\n"
        if matchScore == -1:
        outfileKeep.writelines(srcNewline)
        else: 
            outfileDelete.writelines(srcNewline)
            try:
                os.remove(src)
        except WindowsError:
                print "I was unable to delete this file:"
                outfileKeep.writelines(srcNewline)
            files_removed += 1
            if files_removed:
                print '%d files removed' % files_removed
            else :
                print 'No files removed'
    outfileKeep.close()
    outfileDelete.close()

3voto

bobince Punkte 512550

os.walk(u'.') ist der normale Weg, um native Unicode-Dateinamen zu erhalten, und es sollte gut funktionieren; bei mir funktioniert es.

Ihr Problem liegt stattdessen hier:

srcNewline = src + ", " + str(filename) + "\n"

str(filename) verwendet die Standardkodierung, um die Unicode-Zeichenkette wieder in Bytes umzuwandeln, und da diese Kodierung das Zeichen U+F022(*) nicht enthält, erhalten Sie eine UnicodeEncodeError . Sie müssen wählen, welche Kodierung Sie in Ihrer Ausgabedatei speichern wollen, indem Sie z. B. srcNewLine= '%s, %s\n' % (src, filename.encode('utf-8')) oder (vielleicht besser) die Zeichenketten in Unicode zu halten und sie in die Datei zu schreiben, indem ein codecs.open ed-Datei.

(*: das ist ein Private Use Area Zeichen, das nicht verwendet werden sollte, aber da kann man wohl nicht mehr viel machen...)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X