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 :

[débutant] numpy, lire une portion d'un fichier binaire.


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Par défaut [débutant] numpy, lire une portion d'un fichier binaire.
    Bonjour à tous,

    J'ai un fichier binaire (_pfp) de 16 bytes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [2 0 0 0 3 0 0 0 5 0 0 0 7 0 0 0]
    J'essaye de lire les bytes 8 à 11 (en considérant le premier byte comme le 0ième). Je ne comprend pas pourquoi le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    f = open(_pfp, "rb")
    f.seek(8)
    a = np.fromfile(f, "<I4")
    print a
    m'affiche le 'numpy.ndarray' suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0 0 3 0 0 0 5 0 0 0 7 0 0 0]
    au lieu du résultat souhaité:
    Le premier byte ramené n'est pas le bon et tout le reste du fichier est ramené au lieu de juste 4 bytes, ce que je pensais avoir spécifié avec "<I4".

    Une piste ?

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    La présentation de vos données ne permet pas de savoir ce que vous montrez!
    J'ai un fichier binaire (_pfp) de 16 bytes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [2 0 0 0 3 0 0 0 5 0 0 0 7 0 0 0]
    Comment obtenez vous cela? On devrait plutôt avoir une chaîne de caractères avec des \x...:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> f =  open('test.txt', 'rb')
    >>> f.read()
    '\x02\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x07\x00\x00\x00'
    Essayons de lire cela dans un ndarray:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> f =  open('test.txt', 'rb')
    >>> f.seek(8)
    >>> a = np.fromfile(f, '<I4')
    >>> a
    array([5, 7], dtype=uint32)
    C'est quand même autre chose que:
    m'affiche le 'numpy.ndarray' suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0 0 3 0 0 0 5 0 0 0 7 0 0 0]
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Par défaut
    Merci de votre intérêt.

    Peut-être une précision sur l'objectif:
    Avoir un fichier binaire de (très) grande taille ne contenant que des entiers positifs codés sur 4 bytes. Ce fichier sera susceptible d'être lu de façon intensive par des fonctions ne renvoyant que 4 (ou plusieurs groupes de 4 consécutifs) bytes du fichier. Par exemple j'aurai besoin qu'une fonction puisse lire les bytes 36000 à 36003 puis 24 à 27 etc...

    Le code générant:
    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
    16
    17
    18
    19
    import os.path
    import numpy as np
    import Pgn_F 
     
    _pfp = 'Chemin_du_fichier'
     
    bytnb = 4 #nb de bytes par premier
    if not os.path.isfile(_pfp): #si le fichier n'existe pas
        firstprimes = [2, 3, 5, 7]     #Premiers à écrire
        fpbytes = np.zeros((bytnb * len(firstprimes)), dtype='i') #table vide des bytes correspondants
        for i in range(0, len(firstprimes)): #traitement Premiers
            table = Pgn_F.IntBytCnv(firstprimes[i], bytnb) #conversion int-bytes
            byt1 = bytnb * i #position 1er byte du Premier
            for j in range(byt1, byt1 + bytnb): #traitement bytes du Premier
                fpbytes[j] = table[j - byt1] #tableau de bytes
        #write file
        f = open(_pfp, "wb")
        f.write(fpbytes)
        f.close
    Dans le module de fonctions Pgn_F:
    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
    16
    17
    # convertit entier en tableau de bytes ajusté
    # option nb forcer nb de bytes (ignoré si trop petit)
    def IntBytCnv(ent, nb = 0):
        b = 0
        if ent > 0:
            while ent > 2**(8 * b) - 1:
                b = b + 1
        if b == 0:
            b = 1
        if nb > b:
            b = nb
        table = np.zeros((b), dtype='i')
        for i in range(b, 0, -1):
            a = 2**(8 * (i - 1))
            table[i - 1] = ent // a
            ent = ent - a * table[i - 1]
        return table
    Je me penche sur votre code...

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Citation Envoyé par GuyXL Voir le message
    Peut-être une précision sur l'objectif:
    Avoir un fichier binaire de (très) grande taille ne contenant que des entiers positifs codés sur 4 bytes. Ce fichier sera susceptible d'être lu de façon intensive par des fonctions ne renvoyant que 4 (ou plusieurs groupes de 4 consécutifs) bytes du fichier. Par exemple j'aurai besoin qu'une fonction puisse lire les bytes 36000 à 36003 puis 24 à 27 etc...
    Avec le même fichier que l'exemple précédent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> f =  open('test.txt', 'rb')
    >>> f.seek(8)
    8
    >>> f.read(4)
    b'\x05\x00\x00\x00'
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Par défaut
    Merci beaucoup wiztricks.

    Entre temps j'avais contourné le problème en mettant data type partout à int64 dans les fonctions associées et en faisant ensuite une division puis une multiplication que je ne comprenais pas. Conséquence le fichier contenant 4 nombres sur 4 bytes passait de 32 octets à 64!

    J'ai donc adopté la démarche inverse : tout en int8 et mon fichier fait 16 octets ce qui rend plus 'intuitif' la lecture (4x4=16).

    Merci encore

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Par défaut
    Re,

    J'ai donc deux solutions qui s'offrent à moi, pour récupérer mes entiers 'uint8' soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def FileReadBytes(fpth, foct, nbyt):
        f = open(fpth, "rb")
        f.seek(foct)
        return np.fromfile(f, _dt, nbyt)
    qui marche très bien mais (et cela pourrait être très embêtant pour la suite) je ne sais dire si le fichier est fermé après import.

    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def FileReadBytes(fpth, foct, nbyt):
        f = open(fpth, "rb")
        f.seek(foct)
        a = f.read(nbyt)
        f.close
        return np.frombuffer(a, np.uint8)
    qui semble marcher aussi et lève l'incertitude de fermeture mais est moins directe (passage par des '\x05\x00\x00\x00').

    Comme ces opérations seront faites un nombre considérable de fois j'aimerais lever l'incertitude sur la fermeture et un avis sur la rapidité ou autre considération qui m'echapperait.

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

Discussions similaires

  1. Comment lire une chaîne dans un fichier binaire?
    Par dot-_-net dans le forum Débuter
    Réponses: 9
    Dernier message: 18/05/2008, 23h13
  2. Réponses: 3
    Dernier message: 03/09/2007, 15h07
  3. Lire une ligne dans un fichier
    Par dbozec dans le forum Langage
    Réponses: 3
    Dernier message: 03/05/2006, 23h22
  4. [VB6]Lire une partie d'un fichier .txt
    Par patoch76 dans le forum VB 6 et antérieur
    Réponses: 26
    Dernier message: 02/05/2006, 20h49
  5. Sauvegarder/Lire une classe dans un fichier
    Par Rodrigue dans le forum C++
    Réponses: 10
    Dernier message: 10/09/2005, 14h12

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