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

Entrée/Sortie Java Discussion :

Lire des octets dans un fichier binaire


Sujet :

Entrée/Sortie Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut Lire des octets dans un fichier binaire
    Bonjour,

    Je dois lire des données dans un fichier binaire. On me dit dans la doc que ces données sont stockées à l'octet 12, et sur une longueur de 26 octets.
    En plus, il est dit que "les valeurs binaires codées sur plusieurs octets utilisent l'ordre LFSB (little indian)".

    Comment récupérer les données au format ascii ?

    J'ai essayé d'ouvrir mon fichier avec RandomAccessFile, me positionner dans le fichier avec seek, et lire avec readByte, mais j'obtiens des trucs illisibles.

    Pouvez-vous m'aider ?

    Merci,
    Nico

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 77
    Points : 53
    Points
    53
    Par défaut
    pour lire dans un fichier :
    FileInputStream

    lien sun :
    http://java.sun.com/j2se/1.4.2/docs/...putStream.html

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
       String nomFichier = "blabla.txt";
       fichier=new File(nomFichier);
       // tab de byte qui contiendra ici tout ton fichier 
       tab = new byte[(int)fichier.length()];
     
       // creation du fis
       FileInputStream fis = new FileInputStream(fichier);
       /*lecture dans ton fichier le 1er parametre correspond a la destination
       le 2nd parametre a l'octet de départ et le 3eme parametre combien
       d'octet tu va lire*/
       fis.read( tab, 0, (int)fichier.length() );

  3. #3
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Citation Envoyé par DiverSIG Voir le message
    J'ai essayé d'ouvrir mon fichier avec RandomAccessFile, me positionner dans le fichier avec seek, et lire avec readByte, mais j'obtiens des trucs illisibles.
    Tout dépend comment tu l'interprètes et tu l'affiches.
    Que représentent ces octets ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    Merci, le code de oldscrout marche, ça lit tout le fichier, mais si je veux lire que certains octets (ex ici 5 octets à partir de la position 11), ça plante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    File fichier=new File(f);
    FileInputStream fstream = new FileInputStream(fichier);
     
    byte[] b_temp = new byte[5];
    fstream.read(b_temp, 11, 5);
    for(i=0; i<5; i++) {
         System.out.println(b_temp[i]);
    }
    Pourquoi ?

    Merci,

    Nico

  5. #5
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Citation Envoyé par DiverSIG Voir le message
    Pourquoi ?
    Parce que tu n'utilises pas correctement la méthode "read". Je t'encourage vivement à lire la javadoc.
    Sinon, un exemple possible (codé à La Rache, méthode maintes fois validée et reconnue comme définitivement efficace en informatique....) :
    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
    public byte[] getOctet( File fichier, int debut, int taille ) throws IOExcetion
    {
      FileInputStream input = null;
      byte[] resultat = null;
     
      try
      {
        input = new FileInputStream( fichier );
        input.skip( debut );
        resultat = new byte[ taille ];
        input.read( resultat, 0, taille );
      }
      finally
      {
        if( input != null ) { input.close(); }
      }
     
      return resultat;
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    Maintenant que j'ai récupéré les bytes qui m'intéressent, comment convertir cela en code ascii ?
    je m'explique : j'ai récupéré les 4 bytes correspondant au codage d'un uint32, comment récupérer la valeur à laquelle ça correspond.

    je doit faire la même chose avec des uint8 (1 byte ?), uint16 (2 bytes ?) et des int32 (quelle différence avec des uint32 ??)

    Merci,

    Nic

  7. #7
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    C'est pas pour contredire Dingoban et OldScrouch mais pour ce que tu veux faire la classe RandomAccessFile était tout à fait adaptée.

    RandomAccessFile tout comme FileInputStream permettent de lire un fichier. La différence vient du fait que RandomAccessFile n'étant pas un flux, on peut se positionner très facilement à un point précis du fichier. De plus il contient également des méthodes pout lire des valeurs binaire (c'est également faisable avec FileInputStream mais il faut l'inclure dans un DataInputStream).

    Le problème vient du fait que le fichier utilise l'orde Little Endian alors que java utilise le Big Endian : les octets sont ordonnés dans l'ordre inverse.

    De plus il y a le problème de conversion en type java. En java tous les types(sauf char) sont signés. or tu as :
    uint8 -> un octet non signé -> 0 à 255 -> pas d'équivalent, il faut le stocker dans un short(-32 768 à 32 767)
    uint16 -> deux octets non signés -> 0 à 65536 -> pas d'équivalent, il faut le stocker dans un int(-2^31 à +2^31)
    int32 -> 4 octets signés -> equivalent à un int.

    Donc ça devarit faire quelquechose du genre(j'ai pas testé):
    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
    20
     
    short readUint8 (RandomAccesFile raf){
        byte[] data = new byte[1];
        file.read(data);
        return (short)(0xFFFF&data[0]);
    } 
    int readUint16 (RandomAccesFile raf){
        byte[] data = new byte[2];
        file.read(data);
        return (int)((0xFFFFFFFF&data[0])
                      | ((0xFFFFFFFF&data[1])<<8);
    } 
    int readInt16 (RandomAccesFile raf){
        byte[] data = new byte[4];
        file.read(data);
        return (int)((0xFFFFFFFF&data[0])
                      | ((0xFFFFFFFF&data[1])<<8);
                      | ((0xFFFFFFFF&data[2])<<16);
                      | ((0xFFFFFFFF&data[1])<<24);
    }

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    OK, et si je veux convertir ça en entier signé ?
    exemple :
    j'ai les valeurs hexa des 4 bytes de mon int : 14/63/FF/FF

    c'est du little indian, donc j'inverse l'ordre des bytes => FF/FF/63/14

    et après ?

  9. #9
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Citation Envoyé par DiverSIG Voir le message
    OK, et si je veux convertir ça en entier signé ?
    exemple :
    j'ai les valeurs hexa des 4 bytes de mon int : 14/63/FF/FF

    c'est du little indian, donc j'inverse l'ordre des bytes => FF/FF/63/14

    et après ?
    Par décalage de bit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int mon_entier = ( 0xFF << 24 ) | ( 0xFF << 16 ) | ( 0x63 << 8 ) | 0x14;
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    si je lis directement les bytes au lieu de leur valeur hexa, ça ne marche pas.
    je m'explique :
    je lis les bytes dans mon fichier et je les stocke dans une ArrayList bb2.

    Pour récupérer la valeur, je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    res = ((Byte)bb2.get(0) << 24) | ((Byte)bb2.get(1) << 16) | ((Byte)bb2.get(2) << 8) | ((Byte)bb2.get(3));
    mais au final dans res, j'ai la valeur de bb2.get(0) (1er élément de la ArrayList)

    où est l'erreur ?
    Merci,
    Nico

    en faisant ça, ça a l'air de mieux fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    res = (((Byte)bb2.get(0) & 0xFF) << 24) |
                      (((Byte)bb2.get(1) & 0xFF) << 16) |
                      (((Byte)bb2.get(2) & 0xFF) << 8) |
                      ((Byte)bb2.get(3) & 0xFF);
    les valeurs sont plus conformes à ce que je dois obtenir.

  11. #11
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Effectivement, le "& 0xFF" est obligatoire pour convertir le byte en int dès lors que le byte dépasse la valeur 127.
    Le byte est signé sur 8 bits, le bit de poids le plus fort n'est pas conservé lors du décalage de bit. Mais après conversion en int, le bit de poids le plus fort ne correspond plus au signe puisque le type int est sur 32 bits.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 423
    Points : 133
    Points
    133
    Par défaut
    Dans certains cas, il est dit dans la doc que les nombres sont codés sur 2(ou 4) octets en complément à 2.
    et là, du coup, ça me donne plus les bonne valeurs ...

  13. #13
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Le complément à 2 est une opération basique sur les nombres binaires. Pour retrouver la valeur entière, il suffit de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int mon_entier = ~( complement_2 - 1 );
    L'opérateur "~" permet de calculer le complément à 1.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

Discussions similaires

  1. écrire et lire des octets dans un fichier
    Par toutounesan dans le forum VB.NET
    Réponses: 3
    Dernier message: 23/06/2011, 10h52
  2. Ecrire & Lire des énumérés dans un fichier Texte
    Par WebPac dans le forum Langage
    Réponses: 8
    Dernier message: 18/06/2008, 10h04
  3. [VBS]Lire des données dans un fichier .txt
    Par kacxial dans le forum VBScript
    Réponses: 4
    Dernier message: 28/02/2007, 13h44
  4. Réponses: 2
    Dernier message: 27/06/2006, 14h33
  5. [VBA-E] Lire des valeurs dans un fichier excel
    Par nicobox dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 11/05/2006, 15h40

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