Il semble que le codage du nom de fichier de chaque fichier archivé dans le fichier zip puisse spécifier la présence ou l'absence de l'indicateur UTF-8 (dans la version actuelle), mais le codage autre que UTF-8 ne peut pas être spécifié. ..
Lorsqu'il est compressé dans les paramètres régionaux japonais Windows (selon l'outil), le nom du fichier est écrit en Shift_JIS (CP932). La plupart des Linux et Mac modernes sont UTF-8.
Lors de la décompression d'un fichier zip compressé sur un autre système d'exploitation, il peut être décompressé sans problème s'il a l'indicateur UTF-8, mais si Shift_JIS (CP932) est utilisé, le nom du fichier est brouillé. Cela peut arriver.
Plus précisément, Windows → Linux / Mac, etc. Dans ce cas, vous pouvez utiliser un archiveur tel que ʻunarou corriger le nom de fichier brouillé avec
convmv`.
En dehors de cela, la bibliothèque ZipFile de Python ne reconnaît pas non plus correctement les noms de fichiers.
La bibliothèque ZipFile convertit les octets en chaînes au format UTF-8 s'il existe un indicateur UTF-8, sinon en tant que CP437.
Par conséquent, si vous essayez de développer en utilisant ZipFile.extractall ()
etc., le nom du fichier japonais sera développé avec des caractères déformés.
La solution de contournement consiste à reconvertir ZipInfo.filename
en une chaîne d'octets comme CP437, puis à nouveau en une chaîne avec le codage correct et à l'appeler ZipFile.extract (ZipInfo)
.
import zipfile
f = r'/file/to/path'
with zipfile.ZipFile(f) as z:
for info in z.infolist():
info.filename = info.filename.encode('cp437').decode('cp932')
z.extract(info)
Dans ce qui précède, le codage d'origine est traité comme CP932, mais en réalité ce n'est pas toujours le cas, il est donc préférable d'utiliser un jugement de codage ou un traitement d'exception.
Il n'y a pas de problème si le processus d'extraction à l'aide de ZipFile est exécuté sur un Mac, mais si vous essayez d'extraire sous Windows, une erreur se produira en fonction du nom du fichier.
ZipInfo.filename
a remplacé ʻos.sep par
/. Autrement dit, sous Windows,
` (\ x5c
) est remplacé par /
(\ x2f
).
CP437 est un encodage de caractères à 1 octet, et les caractères d'impression ASCII (\ x20
- \ x7f
) sont compatibles ASCII, donc ce processus de remplacement est effectué (même s'il fait à l'origine partie de caractères multi-octets). Je vais finir. En conséquence, une fois que vous revenez à la chaîne d'octets, un modèle tel que b '\ x90 \ x2f'
apparaîtra.
Shift_JIS (CP932) n'utilise jamais le deuxième octet \ x2f
, donc lorsque vous essayez de convertir à nouveau une telle chaîne d'octets en une chaîne comme CP932, une erreur de décodage se produit. Je vais.
Ce problème se produit lorsque le deuxième octet est le caractère «\ x5c».
alors. C'est un soi-disant «mauvais caractère». (Bien que la raison de l'échec soit différente de celle-ci)
Non. J'ai complètement oublié les mauvais personnages de Shift_JIS (CP932) ces 10 dernières années. De plus, il est livré avec une sphère changeante que shift_JIS (CP932) devient une chaîne d'octets invalide en la remplaçant par \ x2f
.
Les informations de nom de fichier (décodées en CP437) avant le processus de remplacement sont stockées dans ZipInfo.orig_filename
, qui peuvent être utilisées pour résoudre le problème.
import os
import zipfile
f = r'/file/to/path'
with zipfile.ZipFile(f) as z:
for info in z.infolist():
info.filename = info.orig_filename.encode('cp437').decode('cp932')
if os.sep != "/" and os.sep in info.filename:
info.filename = info.filename.replace(os.sep, "/")
z.extract(info)