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 :

Lecture du contenu d'un fichier compressé en mode texte ?


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 39
    Points : 25
    Points
    25
    Par défaut Lecture du contenu d'un fichier compressé en mode texte ?
    Bonjour,
    lorsque j'étais en python 2.7, je pouvais parser un fichier texte compressé pour réaliser mes traitements. Depuis 3.3, les données lues sont binaires et mes traitements échouent:

    Voici un ecm :
    soit un fichier foo.txt, foo.zip (contenant le foo.txt compressé)!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    from zipfile import ZipFile
     
    bar=(ZipFile('foo.zip')).open('foo.txt')
    foo=open('foo.txt','r')
     
    for ligne in foo:
        print(ligne.strip('\n'))
     
    print("Zippé maintenant")
    for ligne in bar:
        print(ligne)
        print(ligne.strip('\n'))

    Résultats en 2.7:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    AAA
    BBB
    CCC
    DDD
    Zippé maintenant
    AAA
    BBB
    CCC
    DDD
    Résultats en 3.3:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    AAA
    BBB
    CCC
    DDD
    Zippé maintenant
    b'AAA\n'
    Traceback (most recent call last):
      File "ecm.py", line 15, in <module>
        print(ligne.strip('\n'))
    TypeError: Type str doesn't support the buffer API
    J'aimerai, si possible éviter de désarchiver temporairement le fichier à lire.

    Cordialement

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 381
    Points : 36 928
    Points
    36 928
    Par défaut
    Salut,
    Avec Python3, les fichiers ouverts 'r' sont lus en unicode et les "str" sont unicode par défaut.

    => Pour avoir des bytes sur le fichier à zipper:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foo=open('foo.txt','rb')
    Par contre, ZipFile().open() retournera maintenant des bytes (en fait pareil qu'avant...) mais dans:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for ligne in bar:
        print(ligne)
        print(ligne.strip('\n'))
    ligne est "bytes" alors que '\n' est "str" (et donc unicode).
    Forcez '\n' à bytes via un b'\n' : çà "fonctionnera mieux".

    Cordialement,
    - W

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Forcez '\n' à bytes via un b'\n' : çà "fonctionnera mieux".
    Merci de cette réponse rapide, je préfèrerai forcer "ligne" en Unicode (en str) puisque il ne s'agissait la que d'un exemple minimum.

    En réalité, mes traitements sur la ligne sont plus complexe, et il ne peuvent être fait que ci celle ci en en 'str'.

    Me reste à trouver comment la convertir en 'str' (j'espérai secrètement qu'un parametre de zipfile m'avait échappé pour me permettre de lire la ligne en 'str' directement)
    @+

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Bonsoir,
    un semble faire l'affaire.

    Cordialement

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 381
    Points : 36 928
    Points
    36 928
    Par défaut
    Salut,

    Effectivement çà le fait pourvu que vous ayez tout "bytes" ou tout "str" et non un mix. Mais .decode suppose connaître l'encoding des fichiers pour fonctionner proprement.

    - W

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Oui, jai du préciser decode('utf-8','ignore'). C'est pour un usage peso, alors je débogue au fur et à mesure.

    Moi qui croyais que python 3.3 allait enfin me permettre d’arrêter de me prendre la tête avec des histoire d'encoding, c''est rapé !

    @+

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 381
    Points : 36 928
    Points
    36 928
    Par défaut
    Salut,

    Citation Envoyé par meles Voir le message
    Oui, jai du préciser decode('utf-8','ignore'). C'est pour un usage peso, alors je débogue au fur et à mesure.
    hmm, utf-8 est le défaut.
    Par contre, 'ignore' fera que les séquences de bytes intraduisibles seront virées.
    est-ce vraiment ce que vous voulez?

    Moi qui croyais que python 3.3 allait enfin me permettre d’arrêter de me prendre la tête avec des histoire d'encoding, c''est rapé !
    Chaque fois que vous devez lire des textes externes et les transformer en Unicode "interne", il faut se poser la question. Python3 change les défauts et évite de mélanger bytes et unicode dans la même séquence.

    Je ne comprends pas trop la nécessité des traitements que vous faites sur les fichiers archivés: si vous y touchez, non seulement vous perdez la conformité avec l'original mais devez décider de les garder en tas de bytes ou de les passer par .decode pour avoir des str.

    Je suis curieux du "pourquoi" de ces traitements.
    - W

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Bonsoir, pour virer les caractère inconnu sur mes fichiers (qui sont ascii en fait), le 'ignore' ne me gène pas.

    Le pourquoi des traitements, pour satisfaire ta curiosité (votre si tu prèfères, mais le tutoiement étant de rigueur sur internet, j'y souscris volontiers) est en fait assez simple.

    Tous les mois, je dois envoyer des fichiers produits par mon établissement à ma tutelle. Les envois sont réalisé avec des outils fournis par le ministère (qui sont soit java, soit dot net, beurk) et les données envoyées (des fichiers txt aux formats ésotériques qui changent régulièrement) sont stockées dans deux archives de type avant /après traitement. chaque fichier zip contient plusieurs de ces fichiers texte.

    Mes "traitements" consistent à récupérer les infos contenues dans ces fichiers pour les coller dans une BDD afin des vérifier les résultats de ma tutelle (et procéder à différentes requêtes). Comme j'ai la flemme d'extraire tout ces fichiers (qui prennent bien moins de place dans leur format zip, certains peuvent faire plusieurs dizaine de milliers de lignes, parfois millions dans de très grosse structure), je traite tout ça directement en les lisant dans le zip, mais n'y apporte aucune modifs.

    Mes traitements sont basé sur la récupération d'un ligne, puis initialisation d'une classe avec cette ligne comme paramètre du self.__init__, la classe en question se chargeant de trouver le bon format et de découper la ligne correctement (et d'y apporter un certain nombre de traitements pour rendre ces données aptes à être digérées par postgresql. J'ai d'ailleurs un grosse soucis de perf a cause de cette approche car l'instanciation (si c'est comme ça qu'on dit) d'un objet prend un temps fou, et sur un fichier de 2 Millions de lignes, c'est long.

    Pour corser le tout, je bosse sous win au boulot, et linux à la maison (je suis de ceux qui emmènent du taff pour le soir).

    En espérant avoir répondu a tes questions

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 381
    Points : 36 928
    Points
    36 928
    Par défaut
    Salut,

    Merci pour ces infos.

    J'ai d'ailleurs un grosse soucis de perf a cause de cette approche car l'instanciation (si c'est comme ça qu'on dit) d'un objet prend un temps fou, et sur un fichier de 2 Millions de lignes, c'est long.
    S'il faut avoir analysé les 2M lignes, il faudra, en effet, du temps pour sortir d'__init__. Aller plus vite devrait être possible en "parallélisant" les traitements.
    Mais ce n'est jamais simple.

    - W

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 19/04/2011, 16h28
  2. Réponses: 3
    Dernier message: 15/02/2010, 09h56
  3. la lecture du contenu d'un fichier
    Par zooffy dans le forum ASP.NET
    Réponses: 2
    Dernier message: 12/01/2009, 14h11
  4. Lecture du contenu d'un fichier
    Par nawal_ensias dans le forum Langage
    Réponses: 2
    Dernier message: 22/06/2007, 13h23
  5. [VB5] |Lecture du contenu d'un fichier .TXRT|
    Par jlb59 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 04/06/2006, 17h16

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