comment lire un fichier qui peut être enregistré en ansi ou unicode en python?
Je dois écrire un script qui prennent en charge la lecture d'un fichier qui peut être enregistré en Unicode ou Ansi (à l'aide de MS est le bloc-notes).
Je n'ai pas d'indication du format d'encodage dans le fichier, comment puis-je supporter les deux formats d'encodage? (le genre d'une façon générique de la lecture de fichiers avec out savoir le format avancé).
Qui version de Python que vous utilisez? 2.x et 3.x poignée Unicode différemment.
Pour l'unicode, vous pouvez utiliser un ByteOrderMark (BOM) en UTF-16 fichiers pour montrer qu'il est en fait unicode, et l'ordre dans lequel les octets sont dans. régulière "ansi" (ascii, je suppose?) il est rare de commencer avec un marqueur.
J'utilise Python 2.7
Méfiez-vous que "ANSI" n'est pas un codage de caractères: John Machin réponse est le seul à ce jour avec une définition précise de ce qu'est "ANSI".
Pour l'unicode, vous pouvez utiliser un ByteOrderMark (BOM) en UTF-16 fichiers pour montrer qu'il est en fait unicode, et l'ordre dans lequel les octets sont dans. régulière "ansi" (ascii, je suppose?) il est rare de commencer avec un marqueur.
J'utilise Python 2.7
Méfiez-vous que "ANSI" n'est pas un codage de caractères: John Machin réponse est le seul à ce jour avec une définition précise de ce qu'est "ANSI".
OriginalL'auteur YSY | 2011-12-11
Vous devez vous connecter pour publier un commentaire.
MS Notepad donne à l'utilisateur un choix de 4 codages, exprimée en maladroite confusion terminologique:
"Unicode" UTF-16, écrit little-endian. "Unicode big endian" UTF-16, écrite big-endian. Dans les deux UTF-16 cas, cela signifie que le MOB va être écrit. Utilisation
utf-16
pour décoder un tel fichier."UTF-8" UTF-8; le bloc-notes explicitement écrit une "UTF-8 BOM". Utilisation
utf-8-sig
pour décoder un tel fichier."ANSI" est un choc. C'est MME de la terminologie de "quelle que soit la valeur par défaut héritage de codage est sur cet ordinateur".
Voici une liste de Windows encodages que je connais et les langues/les scripts qu'ils sont utilisés pour:
Si le fichier a été créé sur l'ordinateur où il est lu, alors vous pouvez obtenir le "ANSI" encodage par
locale.getpreferredencoding()
. Sinon, si vous savez d'où il vient, vous pouvez spécifier quel encodage utiliser si ce n'est pas de l'UTF-16. À défaut, deviner.Être prudent en utilisant
codecs.open()
de lire des fichiers Windows. Les docs disent: """RemarqueLes fichiers sont toujours ouvert en mode binaire, même si aucun mode binaire a été spécifié. Ceci est fait pour éviter la perte de données due à des codages à l'aide de 8-bits. Cela signifie que pas de conversion automatique de '\n' est effectuée sur la lecture et l'écriture.""" Cela signifie que vos lignes dans
\r\n
et vous aurez besoin/envie de dépouiller ceux hors.Mettant tous ensemble:
Exemple de fichier texte, enregistré avec tous les 4 codage des choix, ressemble à ceci dans le bloc-notes:
Voici le code de démonstration:
et voici la sortie lorsqu'il est exécuté dans une fenêtre "Invite de Commande" de la fenêtre à l'aide de la commande
\python27\python read_notepad.py "" t1-*.txt
De choses à connaître:
(1) "cmb" est un fichier système de pseudo-encodage qui n'a pas de pertinence pour le décodage de la contenu de fichiers. Sur un système où le codage par défaut est
cp1252
, il fait commelatin1
(aarrgghh!!); voir ci-dessous(2)
chardet
est très bien à détecter les codages basé sur des scripts non latins (Chinois/Japonais/coréen, Cyrillique, hébreu, en grec), mais pas beaucoup de bon latine, à base de codages (de l'Ouest/Centrale/Europe de l'est, turc, Vietnamien) et n'en connaît pas l'arabe.OriginalL'auteur John Machin
Le bloc-notes enregistre les fichiers Unicode avec une marque d'ordre d'octet. Cela signifie que les premiers octets du fichier sera:
D'autres éditeurs de texte peut ou peut ne pas avoir le même comportement, mais si vous savez que le bloc-notes est utilisé, ce qui vous donnera un décent heuristique de sélection automatique de l'encodage. Toutes ces séquences sont valables dans le codage ANSI que bien, en revanche, il est donc possible pour cette heuristique de faire des erreurs. Il n'est pas possible de garantir que l'encodage correct est utilisé.
Vos commentaires semblent contrairement à l'avis donné dans l'Unicode Marque d'Ordre d'Octet de la FAQ - particulièrement la section "Q: Où est une NOMENCLATURE utile?". Bien sûr, aucun codage de la signature peut toujours mentir à propos de la véritable encodage d'un fichier. Mais pour la plupart des cas, la NOMENCLATURE est un indicateur raisonnablement fiable.
Ce que les Nomenclatures étaient destinés n'est pas pertinent. La question est, étant donné le comportement du bloc-notes, et la connaissance qu'un fichier a été en fait créé par le bloc-notes, quelle est la meilleure stratégie pour la lecture d'un tel fichier. Le fait qu'une telle stratégie implique l'heuristique devrait aller sans dire.
la méthode recommandée pour déterminer l'encodage est de l'avoir explicitement indiqué externe pour le flux de données elle-même. Cependant, parce qu'il y a des protocoles qui ne sont pas de suivre les meilleures pratiques de Microsoft en particulier, la FAQ de la liste des différentes façons de deviner qui sont généralement fiables. L'utilisation d'une NOMENCLATURE, comme une signature a été développé par des personnes qui ne pas ou ne pouvaient pas utiliser les meilleures pratiques, et parfois, nous avons juste à faire face. Bien sûr, l'OMI a une meilleure solution est de suivre Michael Kaplan, des conseils et de l'arrêter à l'aide de bloc-notes de Windows: blogs.msdn.com/b/michkap/archive/2010/02/23/9967789.aspx
Non, je pense que le fait que la méthode n'est qu'une heuristique doit être explicitement indiqué, parce que c'est important de savoir qu'il n'est pas précis à 100% et qu'il y a des façons de le tromper. Comme je l'ai dit ci-dessus, oui, parfois, nous avons juste à faire face avec elle, mais ce n'est pas une raison pour ne parviennent pas à expliquer ou de comprendre ce que nous faisons.
OriginalL'auteur kindall