Frage

Ich benutze python zipfile-Modul zu extrahieren .zip-Archiv (nehmen wir mal diese Datei bei http://img.dafont.com/dl/?f=akvaleir zum Beispiel.)

f = zipfile.ZipFile('akvaleir.zip', 'r')
for fileinfo in f.infolist():
    print fileinfo.filename
    f.extract(fileinfo, '.')

Seine Ausgabe:

Akval�ir_Normal_v2007.ttf
Akval�ir, La police - The Font - Fr - En.pdf

Beide Dateien sind unaccessable nach der Extraktion, weil es ungültige codierte Zeichen in Ihren Dateinamen.Das problem ist zipfile-Modul verfügt nicht über eine option aus, um anzugeben Ausgabe-Dateinamen.

Allerdings "entpacken akvaleir.zip" entgeht dem Dateinamen auch:

root@host:~# unzip akvaleir.zip 
Archive:  akvaleir.zip
  inflating: AkvalВir_Normal_v2007.ttf  
  inflating: AkvalВir, La police - The Font - Fr - En.pdf  

Ich habe versucht, die Erfassung Ausgabe von "unzip-l akvaleir.zip" in meinem python-Programm, und diese beiden Dateinamen sind:

Akval\xd0\x92ir_Normal_v2007.ttf
Akval\xd0\x92ir, La police - The Font - Fr - En.pdf

Wie bekomme ich den korrekten Dateinamen wie das, was unzip-Befehl wird ohne die Erfassung Ausgabe von "unzip-l akvaleir.zip"?

War es hilfreich?

Lösung

Anstelle der extract Methode, verwenden Sie die open Methode und speichern Sie die resultierende pseudofile auf der Festplatte, unter welchem Namen auch immer Sie wünschen, zum Beispiel mit shutil.copyfileobj.

Andere Tipps

Es dauerte einige Zeit, aber ich denke, dass ich die Antwort gefunden.

nahm ich das Wort sollte Akvaléir sein. Ich fand eine Seite Beschreibung darüber, auf Französisch. Wenn ich Ihr Code-Snippet verwendet wurde, hatte ich eine Zeichenfolge wie

>>> fileinfo.filename
'Akval\x82ir, La police - The Font - Fr - En.pdf'
>>> 

Das ist nicht in UTF8 funktionierte, Latin-1, CP-1251 oder CP-1252-Codierungen. Ich fand dann, dass CP863 war eine mögliche kanadische Codierung, so vielleicht ist dies von Französisch-Kanada war.

>>> print unicode(fileinfo.filename, "cp863").encode("utf8")
Akvaléir, La police - The Font - Fr - En.pdf
>>> 

Allerdings habe ich dann lesen Sie die Zip-Spezifikation Dateiformat, das sagt

  

Das ZIP-Format hat historisch   unterstützt nur die ursprüngliche IBM PC   Zeichencodierungssatz, häufig   bezeichnet als IBM-Codepage 437.

     

...

     

Wenn Allzweck Bit 11 gesetzt ist, die   Dateiname und Kommentar muss unterstützt die   Unicode Standard, Version 4.1.0 oder   größer unter Verwendung der Zeichencodierung   von dem UTF-8-Speicher definierten Form   Spezifikation.

des Testen heraus gibt mir die gleiche Antwort wie die kanadische Codepage

>>> print unicode(fileinfo.filename, "cp437").encode("utf8")
Akvaléir, La police - The Font - Fr - En.pdf
>>>

Ich habe eine Unicode nicht Zip-Datei verschlüsselt und ich werde nicht erstellen, um herauszufinden, also werde ich einfach davon ausgehen, dass alle Zip-Dateien, die CP437-Codierung haben.

import shutil
import zipfile

f = zipfile.ZipFile('akvaleir.zip', 'r')
for fileinfo in f.infolist():
    filename = unicode(fileinfo.filename, "cp437")
    outputfile = open(filename, "wb")
    shutil.copyfileobj(f.open(fileinfo.filename), outputfile)

Auf meinem Mac, das gibt

 109936 Nov 27 01:46 Akvale??ir_Normal_v2007.ttf
  25244 Nov 27 01:46 Akvale??ir, La police - The Font - Fr - En.pdf

, welches Register vervollständigt zu

ls Akvale\314\201ir

und zeigt mit einem schön 'é' in meinem Datei-Browser.

Ich lief in ein ähnliches Problem, während meine Anwendung ausgeführt Docker verwenden. Addiert man diese Zeilen in die Dockerfile, fest alles für mich:

RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

Also, ich denke, wenn Sie nicht Docker verwenden, probieren Sie es aus und stellen Sie sicher, locales richtig erzeugt werden und eingestellt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top