Auslesen der Datei dauert ewig



  • Hallo zusammen,

    ich möchte zwei Dateien Binär auslesen, damit ich den Inhalt gegen einander vergleichen kann. Momentan mache ich dies über die alten C-Funktionen fopen, fgetc und fclose. Da LoadFromFile (TStringList) nicht die Datei komplett ausgelesen hat.

    Nun ja, das auslesen funktioniert. Es dauert eben nur ewig für eine 2,3 MB Große JPEG Datei.

    Wenn ich die gleiche Datei in einem HEX-Editor (UltraEdit) öffne, dann geschieht es innerhalb von unter 3 Sekunden.

    Bei meinem Verfahren dauert es solange, dass ich Euch es gar nicht genau sagen kann. Nach einer halben Stunde bin ich ins Bett gegangen. 😉 Am Morgen war dann die Ausgabe jedenfalls da. Der Speicher ist jedenfalls ausgeglichen, wenn ich mir den Prozess beim Task-Manager anschaue.

    Vielleicht habt ihr ja noch eine alternatives Code Beispiel oder könnt meinen "tunen".

    FILE *fStream ;
    
    unsigned int iChar = 0 ;
    AnsiString sSourceContent = "" ;
    
    if ( fStream = fopen( sMyFile.c_str(), "rb" ) ) {
    	do {
    		iChar = fgetc(fStream) ;
    		sSourceContent = sSourceContent + IntToHex( (int) iChar, 2) + " " ;
    	}
    	while ( iChar != EOF ) ;
    
    	ShowMessage(sSourceContent.Trim()) ;
    	fclose(fStream) ;
    }
    

    Hoffe auf konstruktive Vorschläge.

    Viele Grüße
    Heinz



  • eventuell hilft dir ja dieser Beitrag weiter



  • Empfehlungen:
    1. TFileStream verwenden
    2. alles auslesen und in char *c = new char[size] speichern
    3. dann diese arrays char für char vergleichen, dabei kann es sinnvoll zunächst einen 32 pointer zu verwendne, da die CPU internen Operationen alle auf 32 bit optimiert sind und etwas schneller arbeiten. Aber am Ende aufpassen, da könnte ja dann noch 1 Byte übrig bleiben!



  • Guest_611 schrieb:

    Empfehlungen:
    1. TFileStream verwenden

    Und std::auto_ptr.

    Guest_611 schrieb:

    2. alles auslesen und in char *c = new char[size] speichern

    Das ist nicht exceptionsicher und überdies Speicherverschwendung. Ein wenig puffern schadet nicht.

    Guest_611 schrieb:

    3. dann diese arrays char für char vergleichen, dabei kann es sinnvoll zunächst einen 32 pointer zu verwendne, da die CPU internen Operationen alle auf 32 bit optimiert sind und etwas schneller arbeiten. Aber am Ende aufpassen, da könnte ja dann noch 1 Byte übrig bleiben!

    Du erfindest auch gerne das Rad neu, oder? 😉
    http://www.cplusplus.com/reference/clibrary/cstring/memcmp.html



  • @Heinzelmännchen:
    2 Sachen stossen da auf.

    Du liest jedes Byte einzeln aus der Datei - ginge in Blöcken schneller
    2.
    Du vergrössserst nach jedem gelesenen Zeichen das Ergebnis (Ansistring) um 3 Zeichen (Hexzahl + blanc) - da ist der ja dauernd am "Speicher neu Verwalten"

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
      const unsigned int BuffSize=65536;
      unsigned char Buff[BuffSize];
      FILE *fStream ;
      unsigned int iChar = 0;
      unsigned int jChar = 0;
      unsigned long int CharCount=0;
      unsigned int Read=0;
      AnsiString HexBuff;
      AnsiString sSourceContent = "" ;
      AnsiString sMyFile="Pfad & \\ & Name der Datei muss hier her";
      Button5->Tag=0;
      Button5->Enabled=true;
      if ( fStream = fopen( sMyFile.c_str(), "rb" ) )
      {
        do
        {
          Read=fread(Buff,1,BuffSize,fStream);
          if (Read>0)
          {
            sSourceContent=sSourceContent + AnsiString().StringOfChar(' ',3 * Read);
            for (jChar=0;jChar<Read;jChar++)
            {
              HexBuff=IntToHex( (int) Buff[jChar], 2) + " ";
              sSourceContent[3 * CharCount + 1]=HexBuff[1];
              sSourceContent[3 * CharCount + 2]=HexBuff[2];
              sSourceContent[3 * CharCount + 3]=HexBuff[3];
              if (jChar!=EOF )
              { CharCount++;
                if ((CharCount % 8192)==0)
                { CC2->Caption=CharCount;
                  if (Button5->Tag>0)
                  { break;
                  }
                  Application->ProcessMessages();
                }
              }
            }
          }
        }
        while (Read>0);
        Button5->Enabled=false;
        Button5->Tag=0;
    
        ShowMessage(sSourceContent.Trim()) ;
        fclose(fStream) ;
      }
    }
    //---------------------------------------------------------------------------
    

    CC2 ist ein TLabel zur Anzeige der aktuell gelesenen Anzahl
    Button 5 ist zum Abbrechen, der setzt nur seinen Tag auf 1


Anmelden zum Antworten