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

Java Discussion :

Problème extraction d'un fichier binaire


Sujet :

Java

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut Problème extraction d'un fichier binaire
    Bonjour, bonsoir je viens ici car je rencontre un problème assez déroutant et inexpliqué ... Mon but étais de créer un code java permettant de récupérer une image stocké dans un binaire, pour cela nous devions renseignez au code l'adresse de départ de l'image et l'adresse de fin de l'image dans le binaire, et bien sur le nom du binaire. Oui mais voila lors de cette récupération la plus part des caractère sont remplacé par des 00 (en hexa). Même l'entête de l'image avez disparus. Ne comprenant pas j'ai essayé de copier la totalité de mon binaire et là à ma grande surprise, certain caractère était remplacé par des 00... et oui encore.

    Voici mon code :


    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.Scanner;
     
     
    public class Main {
        public static void main(String[] args) throws IOException {
            Scanner scan = new Scanner(System.in);
            RandomAccessFile bFile = null;
            FileOutputStream pFile = null;
            System.out.print("Enter your binary file : ");
            try {
                bFile = new RandomAccessFile(new File(scan.nextLine()), "r");
            } catch (FileNotFoundException e) {
                System.err.println("File not found !");
                e.printStackTrace();
            }
            System.out.print("Enter your output file (with extention) : ");
            try {
                pFile = new FileOutputStream(scan.nextLine());
            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            System.out.print("Enter start address : ");
            long startAddress = Long.parseLong(scan.nextLine(),16);
            System.out.println(startAddress);
            System.out.print("Enter stop address :");
            long stopAddress = Long.parseLong(scan.nextLine(),16);
     
            bFile.seek(startAddress);
            byte[] buf = new byte[(int) (stopAddress - startAddress)];
            bFile.read(buf);
            pFile.write(buf);
            try {
                bFile.close();
                pFile.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
        }
    }

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Bonjour,

    La méthode read() ne remplit pas le buffer. Elle ne peut pas d'ailleurs : si tu étais près de la fin du fichier, le fichier ne contiendrait pas assez d'octets pour remplir le buffer.
    Vu que le buffer n'est pas rempli, les octets qui n'ont pas été touchés sont restés à 0.

    Quand on appelle read(), on ne sait pas combien d'octets seront lus. Ca peut être 1, ça peut être 24643, on sait pas. Il lira au moins 1 octet, et il ne lira pas plus que la taille du buffer. Mais ça peut être n'importe quoi entre les deux. Pour savoir combien d'octets ont été lus, il faut regarder l'int renvoyé par read().

    Donc, solution :
    - toujours regarder combien d'octets ont été lus
    - appeler read() en boucle jusqu'à ce que tous les octets aient été lus.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Merci de ta réponse mais malgré tes conseils ça ne marche toujours pas voici ce que j'ai changé dans mon code :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.Scanner;
     
     
    public class Main {
    	public static void main(String[] args) throws IOException {
    		Scanner scan = new Scanner(System.in);
    		RandomAccessFile bFile = null;
    		FileOutputStream pFile = null;
    		System.out.print("Enter your binary file : ");
    		try {
    			bFile = new RandomAccessFile(new File(scan.nextLine()), "r");
    		} catch (FileNotFoundException e) {
    			System.err.println("File not found !");
    			e.printStackTrace();
    		}
    		System.out.print("Enter your output file (with extention) : ");
    		try {
    			pFile = new FileOutputStream(scan.nextLine());
    		} catch (FileNotFoundException e1) {
    			// TODO Auto-generated catch block
    			e1.printStackTrace();
    		}
    		System.out.print("Enter start address : ");
    		long startAddress = Long.parseLong(scan.nextLine(),16);
    		System.out.println(startAddress);
    		System.out.print("Enter stop address :");
    		long stopAddress = Long.parseLong(scan.nextLine(),16);
     
    		bFile.seek(startAddress);
    		int taille = (int) (stopAddress - startAddress);
    		byte[] buf = new byte[taille];
    		int oLu = 0; 
    		do{
    			oLu = bFile.read(buf);
    			System.out.println("taille : "+taille);
    			System.out.println("oLu : "+oLu);
    		}while(oLu != taille);
    		pFile.write(buf);
    		try {
    			bFile.close();
    			pFile.close();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    	}
    }
    J'ai comme tu as dis boucler sur read() tant que celui ci n'avais pas remplie le buffer entièrement .. mais ça n'a rien changé toujours des 00.

  4. #4
    Membre habitué
    Profil pro
    Opération
    Inscrit en
    Décembre 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Opération

    Informations forums :
    Inscription : Décembre 2012
    Messages : 91
    Points : 188
    Points
    188
    Par défaut
    Tu oublie d’écrire les octets lus !
    Ton code devrait être modifié comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    do{
      oLu = bFile.read(buf);
      System.out.println("taille : "+taille);
      System.out.println("oLu : "+oLu);
       pFile.write(buf,0,oLu);
    }while(oLu  >0);
    //pFile.write(buf); A supprimer

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    A votre code j'ai une jolie erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Exception in thread "main" java.lang.IndexOutOfBoundsException
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(Unknown Source)
    at Main.main(Main.java:43)

  6. #6
    Membre habitué
    Profil pro
    Opération
    Inscrit en
    Décembre 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Opération

    Informations forums :
    Inscription : Décembre 2012
    Messages : 91
    Points : 188
    Points
    188
    Par défaut
    Effectivement j'ai été trop vite.
    En principe le code ci-dessous est plus juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      while ((oLu = bFile.read(buf)) > 0) {
      System.out.println("taille : "+taille);
      System.out.println("oLu : "+oLu);
       pFile.write(buf,0,oLu);
     }

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Toujours même que précédemment des 00 et certains caractères qui sont copier ... mais certain copier et qu'ils sont pas vraiment pas dans le binaire d'origine.

  8. #8
    Membre habitué
    Profil pro
    Opération
    Inscrit en
    Décembre 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Opération

    Informations forums :
    Inscription : Décembre 2012
    Messages : 91
    Points : 188
    Points
    188
    Par défaut
    Ma proposition de code permet d'utiliser un buffer plus petit et de contrôler que tous les bytes lus sont écrits. Dans votre code comme le buffer est de la taille des données à lire, sauf erreur de lecture ou taille de buffer, les données peuvent être lues et écrite en une fois sans boucles.
    Puisque le résultat soit identique, c'est que les données lues ne sont pas structurées comme vous le supposez...

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Je ne vois pas ou peut être un erreur de structure du fichier... car même lorsque je copie le binaire en entier et que je les compare avec un éditeur héxa les fichiers sont différents : certains caractères sont les mêmes, d'autres n'y sont pas, etc
    C'est assez étrange je trouve ..

  10. #10
    Membre habitué
    Profil pro
    Opération
    Inscrit en
    Décembre 2012
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Opération

    Informations forums :
    Inscription : Décembre 2012
    Messages : 91
    Points : 188
    Points
    188
    Par défaut
    Effectivement c'est étrange ! j'ai déjà utilisé ce type de copie entre un inputStream et un outpStream sans problème.

  11. #11
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Moi je dis qu'il faut qu'on voir le code source complet comme il est maintenant. Il y a sûrement une erreur.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    C'est bon tout marche normalement .. l'erreur ne venait pas de mon code, enfin si quand même aussi, mais il venais surtout de l’exécutable qui est impossible a copier sans altérer ses données et je ne comprend pas pourquoi ^^ Même en utilisant le copie du cmd le binaire était altérée .. en tout cas j'ai essayé sur un autre exécutable et ça marche. Donc merci pour toutes vôtres aides.

  13. #13
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Après vérification il y a toujours un problème après avoir testé sur un gif contenue dans un binaire, (ça a fonctionné) j'ai essayer avec un png contenue dans un autre binaire, mais la copie c'est mal passé et le fichier sortant et illisible voici un extrait des deux codes hexa pour que vous voyiez bien :
    Original (le png contenue dans le binaire) :

    Puis le contenue après extraction et copie (celui du fichier sortant donc):

  14. #14
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Rebonjour,

    Je répète qu'il faudrait qu'on voie le code en entier tel qu'il est maintenant.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #15
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Je l'avais déjà donné un peux plus haut mais le revoici :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.Scanner;
     
     
    public class Main {
    	public static void main(String[] args) throws IOException {
    		Scanner scan = new Scanner(System.in);
    		RandomAccessFile bFile = null;
    		FileOutputStream pFile = null;
    		System.out.print("Enter your binary file : ");
    		try {
    			bFile = new RandomAccessFile(new File(scan.nextLine()), "r");
    		} catch (FileNotFoundException e) {
    			System.err.println("File not found !");
    			e.printStackTrace();
    		}
    		System.out.print("Enter your output file (with extention) : ");
    		try {
    			pFile = new FileOutputStream(scan.nextLine());
    		} catch (FileNotFoundException e1) {
    			// TODO Auto-generated catch block
    			e1.printStackTrace();
    		}
    		System.out.print("Enter start address : ");
    		long startAddress = Long.parseLong(scan.nextLine(),16);
    		System.out.print("Enter stop address :");
    		long stopAddress = Long.parseLong(scan.nextLine(),16);
     
    		bFile.seek(startAddress);
    		int taille = (int) (stopAddress - startAddress+1);
    		byte[] buf = new byte[taille];
    		int oLu = 0; 
    		do{
    			oLu = bFile.read(buf);
    		}while(oLu != taille);
    		pFile.write(buf);
    		try {
    			bFile.close();
    			pFile.close();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    	}
    }

  16. #16
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par rayon-gama Voir le message
    Je l'avais déjà donné un peux plus haut
    Voilà. Or, entretemps, jdevbe t'avais donné la solution.

    Dont on ne voit aucune trace dans le code que tu viens fièrement de poster. A nouveau, oui, sans changement.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  17. #17
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Si tu avais mieux lu tu verrais qu'un peux haut il ma dit que son code était pour un buffer plus petit étant donné que j'utilise un buffer beaucoup plus grand(de la taille de ce que je veux récupérer) je n'ai pas besoin de faire comme il avait codé et mon code est bon. De toute façon dans les deux cas j'obtenais le même résultat.

  18. #18
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par rayon-gama Voir le message
    Si tu avais mieux lu tu verrais qu'un peux haut il ma dit que son code était pour un buffer plus petit étant donné que j'utilise un buffer beaucoup plus grand(de la taille de ce que je veux récupérer) je n'ai pas besoin de faire comme il avait codé et mon code est bon.
    J'ai très bien lu et ce raisonnement est faux, tout simplement. Avec un buffer de la bonne taille tu n'es pas obligé de coder comme il a fait, mais en tout cas sa manière à lui marche, et pas la tienne.

    Citation Envoyé par rayon-gama Voir le message
    De toute façon dans les deux cas j'obtenais le même résultat.
    Pour la troisième fois, je demande à voir.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  19. #19
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par rayon-gama Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     		do{
    			oLu = bFile.read(buf);
    		}while(oLu != taille);
    		pFile.write(buf);
    La, il y a clairement un probleme de logique. D'apres la javadoc, read ne garantit pas que l'ensemble du tableau sera remplit. C'est d'ailleurs pour ca qu'il renvoit le nombre de byte lus.
    Bref, sans rentrer dans les détails, quelque soit la taille du buffer, il faut plutot faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while (oLu < taille) {
    oLu += bFile.read(buf, oLu, buf.length-oLu));
     }
    Ceci dit, ca n'explique pas les problemes que tu observes. J'ai testé le code avec un fichier test et pour moi, ca marche (à la remarque que j'ai faite près). Est ce que tu peux poster les parametres que tu utilises pour le fichier (le string que tu comme debut et fin de fichier) ?

  20. #20
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Mai 2012
    Messages : 12
    Points : 1
    Points
    1
    Par défaut
    Pour que vous voyez exactement ce que ça fais je vais vous présenter un exemple que vous pouvez essayer de faire très facilement si vous êtes sur Windows ..
    Vous lancer donc le code pour le binaire vous mettez : C:\Windows\System32\calc.exe (la calculatrice quoi..)
    L'output : Vous mettez ce que vous voulez.
    Le start address : 736C8
    Et le stop address : 748E8
    Et l'a maintenant vous ouvrez calc.exe avec un editeur hexa, vous allez à l'adresse 736C8 et vous verrez l'entête d'une entête PNG (prouvé avec ouverture de la calculatrice avec ResHacker ou j'ai trouvé les mêmes adresses pour cette image).
    Puis vous lancer donc l'extraction de l'image avec mon code.
    Et vous ouvrez le fichier extrait avec un éditeur hexa et vous comparez les deux hexa et vous verrez tout de suite mieux mon problème.
    De plus je l'ai testé avec un logiciel ou j'avais mis moi même un PNG et ça à fait exactement le même problème.
    P.S : Si vous voulez vous rendre compte encore plus du problème modifier un peux mon code pour qu'il copie l'intégralité du binaire et vous verrez que les hexas des deux binaires (l’orignal et la copie) sont différents.

Discussions similaires

  1. Ajout de codes Hexa après extraction d'un fichier binaire
    Par Philippe_Perfect dans le forum Débuter
    Réponses: 6
    Dernier message: 07/06/2010, 20h59
  2. problème ecriture et lecture fichier binaire
    Par gonzo59 dans le forum C++
    Réponses: 5
    Dernier message: 16/04/2009, 20h02
  3. Réponses: 10
    Dernier message: 13/11/2008, 18h12
  4. Problème d'écriture vers fichier binaire
    Par Mr Light dans le forum C++
    Réponses: 6
    Dernier message: 27/02/2008, 21h25
  5. Réponses: 5
    Dernier message: 26/03/2007, 01h30

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