Zwei Dateien miteinander vergleichen



  • Hallo,

    ich habe diesen Code geschrieben um zwei Dateien miteinander zu vergleichen funktioniert auch ganz gut aber ich wuerde gern eine noch schnellere Methode haben, wie kann man z.B den gesamten Inhalt der Datei in einem mal einlesen ?

    in[0].open(filename[0].c_str());
    	in[1].open(filename[1].c_str());
    
    	while(getline(in[0],temp[0]) && getline(in[1],temp[1]))
    	{
    		value[0]+=temp[0];
    		value[1]+=temp[1];
    	}
    
    	if(value[0]==value[1])cout << "Beide Dateien haben den gleichen Inhalt.\n";
    	else cout << "Ungleich!\n";
    


  • Nicht sehr performant Als allererstes solltest du die Größen der Dateien miteinander vergleichen
    wenn diese ungleich sind, hast du dein Ergebnis.
    Geh doch die Datei Byte für Byte oder besser Word für Word durch.
    {hatte grad nen Denkfehler}



  • md5 hash



  • Wenn ich es so mache ist es sicher schneller aber irgendwer hat mal gesagt das sei nicht std konform oder so 😕 😕 😕

    in[0].seekg(0,ios::end);
    in[1].seekg(0,ios::end);
    
    laenge[0] = in[0].tellg();
    laenge[1] = in[1].tellg();
    
    if(laenge[0]==laenge[1])cout << "Beide Dateien haben den gleichen Inhalt.\n";
    else cout << "Ungleich!\n";
    


  • Das zweite funktioniert natuerlich nur wenn in einer Datei mehr oder wenger Zeichen vorhaden sind, wenn die gleiche Anzahl aber unterschiedliche Zeichen vorhanden sind geht es natuerlich nicht.



  • Der Test auf die Längen ist nur ein Hinweis, ob die Dateien ungleich sind.
    Wenn die Längen ungleich sind, brauchst Du nicht weiter zu prüfen.

    Üblich ist es - wie "hash" schreibt - einen Hash-Algorithmus wie z.B. MD5 zu verwenden. Dort wird aus jeder Datei (unter Berücksichtigung aller Zeichen) ein Wert berechnet. Wenn die Werte unterschiedlich sind, sind die Dateien mit einer gewissen Wahrscheinlichkeit nicht gleich. Die Wahrscheinlichkeit hängt vom verwendeten Algorithmus ab, bei MD5 ist es praktisch sicher, dass sie nicht gleich sind.

    Dein Ansatz dürfte relativ langsam sein, weil Du die strings alle addierst. Bei großen Dateien kann die permanente Kopiererei Zeit kosten. Du könntest Deine Routine beschleunigen, in dem Du jede Zeile vergleichst und wenn der erste Unterschied auftritt, dann brichst Du ab.



  • Imo ist es schneller zeichenweise zu vergleichen als einen MD5-Hash zu berechnen.



  • Ja das klingt alles sehr logisch. Ist MD5 denn soviel schneller?? Es muss doch auch erstmal diesen Wert berechnen und die Datei muss ja auch eingelesen werden.



  • Ein zeichenweiser Vergleich ist schneller sein als ein Hash. (Hätte man vielleicht vorher dran denken dürfen 🙄). Insbesondere, wenn Du erwartest, dass die Dateien in der Regel unterschiedlich sind. Dann liest Du ja nur bis zum ersten unterschiedlichen Zeichen ein.

    Der Hash ist genau dann hilfreich, wenn Du den Vergleich mehrfach ausführen musst, weil Du den Hash nur einmal berechnen musst. (Z.B. doppelte Dateien auf der Festplatte finden)



  • Öffne die Dateien binär und lese sie in einen buffer rein mit read().
    Dann einfach mit gcount() schauen ob die Länge des eingelesenen ungleich ist wenn ja dann sind die Dateien halt ungleich.

    Wenn nicht halt einfach den Inhalt der beiden Puffer vergleichen und das solange bis das ende der Dateien erreicht wurde 😃

    char buf1[1024], buf2[1024];
    
    ...
    
    do {
         datei1.read((char*)buf1, sizeof(buf1));
         datei2.read((char*)buf2, sizeof(buf2));
    
         if(datei1.gcount() != f2.gcount())
         {
              cout <<"Ungleich";
              // Dateien schließen
              return 0;
         }
    
         //Puffer Inhalte vergleichen
    
         for(int i=0;i<datei1.gcount();++i)
             if(buf1[i] != buf2[i]
             {
                cout <<"Ungleich";
                // Dateien schließen
                return 0;
             }
       } while (!datei1.eof() && !datei2.eof());
    
       cout <<"Gleich";
    
      // blablabla
    

    EDIT:: Irgendwie schaffe ich es immer der letzte auf einer Seite zu sein 😃 😃



  • Ich würde es so machen

    1. Vergleich der größe ( wenn unterschiedlich gleich stoppen )
    2. datei öffnen und

    solange true zeilenweise einlesen
    die akt. zeile von a mit b vergleichen, falls ungleich dann FLAG gleich auf FALSE setzen und nicht weiter prüfen



  • ich machs immer so:

    -größe vergleichen... wenn ungleich abbrechen
    -schaun ob beide leer sind... wenn ja abbrechen
    -buffer mit größe dateigröße * 2 anlegen
    -die eine in die erste hälfte kopiern, die zweite in die zweite hälfte
    -memcmp aufrufen um den speicherbereich zu vergleichen

    wenn ich viele dateien vergleich leg ich außerdem noch n extrabuffer von 1mb an und allokier nur neuen speicher wenn dateigröße * 2 > 1mb



  • Ich glaube es ist schneller wenn man in kleineren Blöcken vergleicht, dann muss man nicht immer die ganze Datei einlesen. Z.b. immer 128bytes oder so...



  • hmm stimmt
    vorausgesetzt die dateien unterscheiden sich nich am ende



  • Ich glaube der Threaderstelle wollte nur wissen ob "gleich" oder "ungleich".

    😃



  • Thomas Millan schrieb:

    Hallo,
    ich wuerde gern eine noch schnellere Methode haben

    nö denk ich nich :p



  • 128Bytes sind zu klein -> zu viele Plattenzugriffe

    Wenns optimal sein soll immer die komplette übertragbare Blockgröße einlesen.



  • frosty schrieb:

    128Bytes sind zu klein -> zu viele Plattenzugriffe

    Wenns optimal sein soll immer die komplette übertragbare Blockgröße einlesen.

    Gibts nen Unterschied zwischen der max. übertragbaren Blockgröße und der Blockgröße des Dateisystems?



  • Ja gibt es. Die Blockgröße innerhalb des Dateisystems kann eigentlich fast beliebig gewählt werden. Dafür muß man sich nur mal verschiedene Betriebssysteme und die FS Blockgrößen ansehen. Bestes Beispiel UNIX/Linux: Unix SVR3 512Bytes, Linux 4096Bytes. Kann aber bei Linux auch verändert werden.


Anmelden zum Antworten