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:
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:
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:
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();
} |