IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

problème de lecture/décodage d'un fichier texte


Sujet :

Python

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    avril 2007
    Messages
    250
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : avril 2007
    Messages : 250
    Points : 254
    Points
    254
    Par défaut problème de lecture/décodage d'un fichier texte
    Bonjour,

    Je travaille sur une machine XP SP3, et avec une version Python 3.2.2.
    sys.stdout.encoding vaut cp850.

    En résumé, je teste une application qui génère des fichiers de trace volumineux. Et l'encodage du fichier n'est pas indiqué. Et mon idée est de créer un script python qui analyse ces fichiers de trace pour extraire les informations pertinentes (pour l'instant je regarde la présence du mot-clef ODD).

    Mon souci est que lorsque je lis ces fichiers de trace ligne par ligne, certaines lignes ne sont pas lues car elle contiennent un "hiéroglyphe" dont la valeur est 0x81. Cf. extrait des traces à analyser :

    "OUV/PION 2H30\x00R\x00ŒÊ\x00ðŁ\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

    Il s'agit d'un string de 20 caractères. Ce string n'a a priori pas été initalisé avec des caractères null. Les carrés blancs correspondent à la valeur 0x81.

    Et voici le bout de code qui tente de lire le fichier de trace:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    idx_line = 0
    f = open(nom_complet, "r", encoding=sys.stdout.encoding)
      while f :
        read_data = f.readline()
        idx_line += 1
        if not read_data :
          break
        if read_data.find("|ODD") >= 0 :
          my_logger.debug("ODD message found at line %d : %s" % (idx_line, str(read_data)))
        else :
          my_logger.warning("No ODD message found")
     
    f.close()
    D'après ce bout de code, je devrais lire toutes les lignes. Or, je ne lis pas celles qui ont le caractère 0x81. Et j'ai cherché sur le net mais là je suis bloqué.

    Ou alors une idée serait de lire le fichier de trace une première fois pour remplacer les caractères 0x81 par des caractères null 0x00. Et ensuite de faire mon traitement, comme indiqué dans le code.

    Toutes les idées sont les bienvenues. Merci d'avance

  2. #2
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    Oui, mais non. Normalement, pas besoin de préciser l’encoding du fichier à l’ouverture, python le détecte tout seul… Et en tout cas, il y a peu de chance que ton fichier soit en cp850.

    Et c’est surement pas while f: non plus… Plutôt quelque chose comme ça, non*?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    idx_line = 0
    f = open(nom_complet, "r", encoding=sys.stdout.encoding)
    for idx_line, read_data in enumerate(f):
        if read_data.find("|ODD") >= 0 :
            my_logger.debug("ODD message found at line %d : %s" % (idx_line, str(read_data)))
        else :
            my_logger.warning("No ODD message found")
     
    f.close()

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    avril 2007
    Messages
    250
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : avril 2007
    Messages : 250
    Points : 254
    Points
    254
    Par défaut
    Dans la première version, je n'avais précisé l'encoding, et la lecture de ces carrés blancs (valeur hexa : 0x81) provoquent la levée d'une exception (UnicodeDecodeError de mémoire).

    Merci, je vais essayer çà demain.

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Entre 0x81 et 0x9f cela vas devenir compliqué sous xp et Python 3...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    filein = open(nomfichier, 'rb')
    for idx_line, read_data in enumerate(filein):
        if b"|ODD" in read_data:
            print("ODD message found at line {}".format(idx_line))
        else :
            print("No ODD message found")
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    A noter que le type bytes a les méthodes du type str.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> print(dir(type(b'a')))
    ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'center', 'count', 'decode', 'endswith', 'expandtabs', 'find', 'fromhex', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    >>> print(dir(type('a')))
    ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    Et que c'est un moyen de se sortir du souci d'encodage de la console Windows.
    Et puis de toute manière sous Python pour les fichiers c'est du bytes <=> string.

    Note:
    Voir aussi str() et repr() pour la suite du code.
    A lire:
    Les PEP sur le sujet.
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    avril 2007
    Messages
    250
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : avril 2007
    Messages : 250
    Points : 254
    Points
    254
    Par défaut
    Je viens d'essayer en lisant le fichier en mode binaire, et effectivement ça fonctionne.
    Merci beaucoup.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lecture et décodage d'un fichier texte: Solution ou leurre?
    Par j.p.mignot dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 19/01/2008, 15h33
  2. lecture/écriture dans un fichier texte
    Par the watcher dans le forum Delphi
    Réponses: 23
    Dernier message: 15/05/2007, 11h57
  3. Problème de lecture de fin de fichier (eof(fichier))
    Par jailbomba dans le forum Pascal
    Réponses: 2
    Dernier message: 21/02/2007, 17h50
  4. [VB.NET]Problème de lecture et écriture sur fichier texte
    Par zouhib dans le forum Windows Forms
    Réponses: 25
    Dernier message: 23/05/2006, 16h30
  5. [RegEx] Lecture/transformation de mon fichier texte
    Par charlysquare dans le forum Langage
    Réponses: 4
    Dernier message: 24/04/2006, 15h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo