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

 C++ Discussion :

Comparer deux fichiers bit à bit


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Par défaut Comparer deux fichiers bit à bit
    Comment comparer 2 fichiers bit à bit ?

    Bonjour à tous et encore merci pour votre aide et patience pour les « non professionnel » en programmation.
    Pourquoi ce programme, l’anecdote vaut le coup : Je bosse normalement dans le son. J’ai quelques personnes autour de moi dissent que le son change si l’on fait des copies.
    Ce petit programme va donc servir simplement à comparer deux exemplaires d’un même fichier copié x fois et nous dire s’il y des différences.
    On en déduira que non et donc que la différence de son est due : au débit du matériel de stockage, à l’interface de ce matériel de stockage, au logiciel en fonction de la piste utilisé ( algo interne )… à voir.

    Peut être avec vous une autre méthode… je suis toujours preneur.

    Voici la mienne :
    J’utilise deux Flux : A et B et je les compare.

    1er test avec le .tellg() sur le fluxB en commentaire.
    Pour commencer je ne comprends pas pourquoi ligne 44 :
    Si je fait un .tellg () sur un seul des flux ils commence à se décaler. Comme si la lecture de la position faisait avancer le pointeur de flux d’un octet. Normal ou étrange ?

    2eme test en activant les deux .tellg()
    Là la comparaison entre deux fichiers identique se passe bien mais je ne comprends le pas entre deux positions. Vu que j’ai mis une variable « bufferSize » pour remplir un tableau de 10char = 10 octets avec le flux. Et meme si je me trompe dans le nombre d’octet (char = 1/2octet ou 2*octets) le pas devrait être régulier.
    Sur un petit fichier 213 Oct le pas diminue : 45 – 41 – 36 – 26 – 22 – 17 – 16 - 10
    Et le pas change aussi en fonction de la taille des fichiers : sur un fichier de 170ko j’obtiens des pas de 10 à 494.
    Mystère !

    Du coup j’ai vraiment l’impression de ne pas bien comparer les ficher et des sauter des informations. Merci d’avance.

    Le code fonctionne. Pour l’utiliser mettre au niveau de l’exécutable deux fichiers renommé : testA.txt et testB.txt
    c’est juste que l’application une fois finie aura une petite interface graphique créé avec la lib Qt.

    main.cpp
    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
     
    #include <QApplication>
    #include <string>
    #include <iostream>
    #include <fstream>
    #include "CompareFiles.h"
     
    int main(int argc, char* argv[])
    {
        QApplication app(argc, argv);
     
        CompareFiles test;
     
        return app.exec();
    }
    CompareFiles.h
    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
    #ifndef COMPAREFILES_H
    #define COMPAREFILES_H
     
     
    class CompareFiles
    {
      public:
        CompareFiles(std::string a ="testA.txt", std::string b="testB.txt", int buff = 10, int delta = 4);
        virtual ~CompareFiles();
      protected:
      private:
        void compare();
        double tailleFichier( std::ifstream *flux );
        void affichageDiff(int i);
        void affichageDiff(char* bufA, char* bufB, int i);
     
        std::ifstream fluxA;
        std::ifstream fluxB;
        double tailleA, tailleB;
        int bufferSize;
        int deltaDiff;
    };
     
    #endif // COMPARFILES_H
    CompareFiles.cpp
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <bitset>
    #include "CompareFiles.h"
     
     
    using namespace std;
     
    CompareFiles::CompareFiles(string a , string b , int buff, int delta )
                            : bufferSize(buff), deltaDiff(delta)
    {
      fluxA.open( a.c_str(), ios::in );
      if ( fluxA ) tailleA = tailleFichier ( &fluxA );
      else cerr << "Probleme dans le constructeur du flux A" << endl;
     
      fluxB.open( b.c_str(), ios::in );
      if ( fluxB ) tailleB = tailleFichier ( &fluxB );
      else cerr << "Probleme dans le constructeur du flux B" << endl;
     
      compare();
      cerr << "Fin";
    }
     
    void CompareFiles::compare(){
      int positionA, positionB;
      char*bufferA;
      char*bufferB;
     
      if ( tailleA == tailleB ) {
        // allocate memory:
        bufferA = new char [bufferSize];
        bufferB = new char [bufferSize];
     
        double counter = 0;
        while ( fluxA.good() && fluxB.good() && fluxA.tellg()< tailleA ) {
     
          // read data as a block:
          fluxA.readsome (bufferA,bufferSize);
          fluxB.readsome (bufferB,bufferSize);
     
          cerr << "position du flux : " << fluxA.tellg() << endl;
          // !!!!!!!!!!!!!!!!!!!!!!!!!!
          cerr << "position du flux : " << fluxB.tellg() << endl; // ici faut m'expliquer
          // !!!!!!!!!!!!!!!!!!!!!!!!!!
     
          for ( int i=0; i<bufferSize; i++ ) {
            if ( bufferA[i] != bufferB[i] ) {
              positionA = fluxA.tellg(); // On garde la position pour y revenir.
              positionB = fluxB.tellg(); // On garde la position pour y revenir. Normalement ils devraient avoir la meme position.
     
              cerr << "position du fluxA detect Err: " << positionA << endl;
              cerr << "position du fluxB detect Err: " << positionB << endl;
              cerr << "counter : " << counter << "  bufferSize : " << bufferSize << "  i : " << i << endl;
              cerr << "difference entre A et B à l'octet : " << counter*bufferSize + i << endl;
     
              affichageDiff(bufferA, bufferB, i);
              fluxA.seekg(positionA);
              fluxB.seekg(positionB);
            }
          }
          counter++;
        }
     
        delete[] bufferA;
        delete[] bufferB;
     
      }
      else cerr << "la taille des fichiers est differente" << endl;
    }
     
    double CompareFiles::tailleFichier( ifstream *flux ) {
      // determine la taille d'un fichier
      double length;
      flux->seekg (0, ios::end);
      length = flux->tellg();
      flux->seekg (0, ios::beg);
      cout << "taille " << length << endl;
      return length;
    }
    void CompareFiles::affichageDiff(int i){
     
      cerr << "position err : " << i << endl;
     
      if (i>deltaDiff) i-=deltaDiff;
      else i=0;
     
      cerr << "position du flux pour err : " << i << endl;
     
      fluxA.seekg(i);
      fluxB.seekg(i);
     
      for ( int k = 0; k<2; k++){
        if (k==0){
          cerr << "A : ";
          //fluxA.seekg(i);
        }
        else {
          cerr << "B : ";
          //fluxB.seekg(i);
        }
        for (int j = 0; j < 2*deltaDiff+5; j++) {
          if (k==0) cerr << "p" << fluxA.tellg() << "." << fluxA.get() << " ";
          else cerr << "p" << fluxB.tellg() << "." << fluxB.get() << " ";
        }
        cerr << endl;
      }
    }
    void CompareFiles::affichageDiff(char *bufA, char *bufB, int i){
      // cerr << b2;
      cerr << "Element A " << std::bitset<8>(bufA[i-1]) << " " << std::bitset<8>(bufA[i]) << " " << std::bitset<8>(bufA[i+1]) <<endl;
      cerr << "Element B " << std::bitset<8>(bufB[i-1]) << " " << std::bitset<8>(bufB[i]) << " " << std::bitset<8>(bufB[i+1]) << endl;
    }
     
     
     
     
    CompareFiles::~CompareFiles()
    {
      fluxA.close();
      fluxB.close();
    }

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Je n'ai pas bien regardé dans le code mais peut qu'il faut ouvrir les fichiers en binaire ? Je ne suis pas sûr que l'ouverture par défaut d'un fichier soit en binaire mais plutôt en mode texte (avec interprétation et saut de certains caractères).
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Par défaut
    Ok Merci je teste tout de suite. c'est vrai! suis je bête....

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Par défaut
    Super merci le Point 2 est résolu!
    en revanche j'ai toujours le même phénomène sur le point 1 je pense que c'est propre au fonctionnement de la fonction mais si quelqu'un peut me le confirmer.
    Merci ram-0000 pour cet œil de lynx.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Par défaut
    Suite à quelques teste :
    si on modifie la valeur par défaut du bufferSize dans compareFiles.h
    je n'ai plus de problème dés que la valeur est supérieure a 511. Pourquoi?
    Là je crois qu'il faut un fou furieux des Jeans. Mais en info... je ne connais pas ce nombre magique.

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Pourquoi ne pas juste calculer les hash MD5 des differents fichiers et comparer ? Car ouvrir, lir et comparer les fichiers, cest un poil overkill
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

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

Discussions similaires

  1. comparer deux fichier .xls
    Par oursquetaire dans le forum Excel
    Réponses: 6
    Dernier message: 06/07/2006, 16h52
  2. [JDOM] Comparer deux fichiers XML en Java
    Par calimero2611 dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 30/06/2006, 11h19
  3. Comparer deux fichier
    Par Taz_8626 dans le forum Langage
    Réponses: 3
    Dernier message: 20/06/2006, 11h46
  4. comparer deux fichiers avec une api windows
    Par sweetdreamer dans le forum Windows
    Réponses: 4
    Dernier message: 25/05/2006, 22h10
  5. Fonction c qui compare deux fichiers ???
    Par babyface dans le forum C
    Réponses: 4
    Dernier message: 19/11/2005, 13h07

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