Énumération de fichiers japonais avec le système Python2 sous Windows (contre-mesure du problème 5C)

Étant donné que le traitement des caractères multi-octets est encore délicat dans la série Python 2 sous Windows, si vous écrivez normalement le processus d'énumération de fichiers, le processus d'énumération fonctionne bien lorsqu'un caractère spécifique ("table", "so", etc.) apparaît dans le chemin du fichier. Cela peut ne pas fonctionner. Ce qu'on appelle problème 5C.

Liste des fichiers utilisés pour ce test

C:/test
  filelist.py
Tesuto/
    a1.txt
    a2.txt
table/
    hyo1.txt
    hyo2.txt
Table à l'intérieur/
      hyo10.txt
      hyo11.txt

Un script qui écrit normalement l'énumération des fichiers

filelist.py


# -*- coding: utf-8 -*-
import os
SEP = os.sep
def filelist(dir_path):
    for item in os.listdir(dir_path):
        file_path = dir_path + SEP + item
        print(file_path)
        if os.path.isdir(file_path):
            filelist(file_path)
# test
script_dir = os.path.dirname(os.path.abspath(__file__))
filelist(script_dir)

Résultat d'exécution

C:\test\filelist.py
C:\test\Tesuto
C:\test\Tesuto\a1.txt
C:\test\Tesuto\a2.txt
C:\test\table
C:\test\table\table

L'énumération dans le chemin d'accès qui contient la "table" ne fonctionne pas.

Mesures (mesures par décodage)

@wonderful_panda m'a appris. Si vous faites .decode ('cp932') après avoir obtenu le chemin du fichier, vous pouvez énumérer les fichiers sans aucun problème.

# -*- coding: utf-8 -*-
import os
SEP = os.sep
def filelist(dir_path):
    for item in os.listdir(dir_path):
        file_path = dir_path + SEP + item
        print(file_path)
        if os.path.isdir(file_path):
            filelist(file_path)
# test
script_dir = os.path.dirname(os.path.abspath(__file__.decode('cp932')))
filelist(script_dir)

Résultat d'exécution

C:\test\filelist.py
C:\test\Tesuto
C:\test\Tesuto\a1.txt
C:\test\Tesuto\a2.txt
C:\test\table
C:\test\table\hyo1.txt
C:\test\table\hyo2.txt
C:\test\table\中のtable
C:\test\table\中のtable\hyo10.txt
C:\test\table\中のtable\hyo11.txt

L'énumération dans le chemin contenant la "table" a également réussi.

Contre-mesure (ancienne. Contre-mesure par répertoire courant)

La contre-mesure par décodage est extrêmement intelligente, mais je laisserai la contre-mesure que j'ai écrite avant de vous en parler.

filelist.py


# -*- coding: utf-8 -*-
import os
SEP = os.sep
def filelist2(dir_path):
    old_dir = os.getcwd()
    os.chdir(dir_path) #Changer le répertoire courant.
    for item in os.listdir("."):
        file_path = dir_path + SEP + item
        print(file_path)
        if os.path.isdir(item):
            filelist2(file_path)
    os.chdir(old_dir) #Restaurer le répertoire actuel.
# test
script_dir = os.path.dirname(os.path.abspath(__file__))
filelist(script_dir)

Si vous transmettez un chemin contenant des caractères 5C à os.listdir, un problème se produira. Par conséquent, au lieu de passer directement le chemin, définissez le répertoire actuel sur le chemin cible à l'avance et définissez le répertoire actuel sur os.listdir. Passez `". ```Indiquer le répertoire. Cela permet à l'énumération d'être effectuée normalement.

Résultat d'exécution

C:\test\filelist.py
C:\test\Tesuto
C:\test\Tesuto\a1.txt
C:\test\Tesuto\a2.txt
C:\test\table
C:\test\table\hyo1.txt
C:\test\table\hyo2.txt
C:\test\table\中のtable
C:\test\table\中のtable\hyo10.txt
C:\test\table\中のtable\hyo11.txt

L'énumération dans le chemin contenant la "table" a également réussi.

À propos de la série Python3

Même sous Windows, avec Python 3.5 etc., l'énumération des fichiers peut être effectuée normalement sans prendre de mesures comme celle-ci. S'il s'agit d'un nouveau programme connu pour effectuer le traitement de chaînes de caractères multi-octets, il est prudent de commencer avec la série Python 3 au lieu de la série Python 2.

Bonus: résolution de problèmes 5C en PHP

J'ai essayé d'énumérer les fichiers par la même méthode (changer le répertoire actuel) avec PHP sous Windows, mais cela n'a pas fonctionné. J'ai essayé de capter beaucoup d'informations, mais en conclusion, il ne semble pas y avoir de solution en PHP?

This is not possible. It's a limitation of PHP. PHP uses the multibyte versions of Windows APIs; you're limited to the characters your codepage can represent.

If you set a breakpoint at readdir_r() in win32\readdir.c, you'll see that FindNextFile already returns a filename with question marks in place of the characters you want, so there's nothing you can do about it, apart from patching PHP itself.

Recommended Posts

Énumération de fichiers japonais avec le système Python2 sous Windows (contre-mesure du problème 5C)
OpenJTalk sur Windows10 (parler japonais avec Python depuis la construction de l'environnement)
Fichier CGI Python créé sous Windows
Premiers pas avec Python 3.8 sous Windows
[C] [python] Lire avec AquesTalk sous Linux
Remarques sur la réalisation de l'OCR japonais avec Python
Python sur Windows
Installez OpenCV 4.0 et Python 3.7 sur Windows 10 avec Anaconda
Développer des applications Windows avec Python 3 + Tkinter (fichier exe)
Extraire le zip avec Python (prend en charge les noms de fichiers japonais)
Défiez AtCoder (ABC) 164 avec Python! Un problème ~ C
Faire un point d'arrêt sur la couche c avec python
Python à partir de Windows 7
python basic ② sous windows
PIL en Python sur Windows8 (pour Google App Engine)
Installez python sur Windows
Créer Python3 pour Windows 10 sur ARM avec Visual Studio 2019 (x86) sur Windows 10 sur ARM
Activer Python virtualenv sous Windows
Python avec VSCode (Windows 10)
Envoyer du courrier japonais avec Python3
Exécutez python avec PyCharm (Windows)
Installer watchdog sur Windows + Python 3.3
Solution de contournement pour sys.argv non transmise lors de l'exécution d'un script Python avec uniquement le nom de fichier sur Python2.7 sous Windows
Dessiner un fichier netCDF avec python
Développement Python + Kivy sous Windows
Sphinx-autobuild (0.5.2) sous Windows7, Python 3.5.1, Sphinx 1.3.5
Installation de Python la plus rapide sous Windows
Créer un environnement Python sur Windows
Analyse morphologique japonaise avec Python
Construire un environnement Python avec Windows
J'ai exécuté python sur Windows
Système de support de présentation avec Python3
[Python] [Chainer] [Windows] Installer Chainer sous Windows
Utiliser Python sur Windows (PyCharm)
Synchronisation de l'heure (Windows) avec Python
Télécharger le fichier csv avec python
Bloguer avec Pelican sur Windows
Créez un environnement Python 2.7 64 bits avec TDM-GCC et MinGW-w64 sous Windows 7
[Commentaire d'AtCoder] Gagnez le problème ABC165 C "Many Requirements" avec Python!
Résoudre ABC163 A ~ C avec Python
Mémo de construction de l'environnement Python sur Windows 10
Extraire le fichier xz avec python
Détection de visage avec YOLO Face (Windows10, Python3.6)
Appeler C depuis Python avec DragonFFI
Python 3.6 sous Windows ... et vers Xamarin.
Installation de Kivy sur Windows10 64 bits Python3.5
Conseils sur l'entrée / la sortie de fichier Python
Construction de l'environnement Anaconda Python sous Windows 10
[Python] Ecrire dans un fichier csv avec Python
[Automatisé avec python! ] Partie 1: fichier de configuration
Téléchargement de fichiers implémenté avec Python + Bottle
installation de python2.7 dans un environnement Windows 32 bits
Dessinez le japonais avec matplotlib sur Ubuntu
Installez Python sur Windows + pip + virtualenv
Sortie vers un fichier csv avec Python
ABC166 en Python A ~ C problème