status beim öffnen einer datei anzeigen



  • nebel schrieb:

    dabei habe ich ftell und fgetpos gefunden was mit die aktuelle position angibt, das macht aber das auslesen der datei viel, viel langsamer. gibt es denn da nichts anderes?

    Du solltest vor allem nicht bei jedem eingelesenen Zeichen den Status anzeigen. Berechne den prozentualen Fortschritt und zeige den Status z.B. nur bei jeder 5%-igen Änderung an.



  • ich habs jetzt so gemacht, was eigentlich ganz gut funktioniert und nur minimale verluste einbringt.

    hab ne variable in der do-while-schleife mitlaufen.

    if((file = fopen((StartDirectory+sr.Name).c_str(), "rb")) != NULL)
          {
            FormMain->StatusBar->Panels->Items[0]->Text = dir;
            FormMain->StatusBar->Panels->Items[1]->Text = sr.Name;
            FormMain->StatusBar->Panels->Items[2]->Text = (IntToStr(sr.Size/1024) + " KB     ");
    
            iUpdatePos = 0;
            FormMain->ProgressBar->Max = sr.Size;
    
            do // datei stückchenweise einlesen
            {
              Application->ProcessMessages();
              cBuffer = fgetc(file);
    
              // ohne die zeichen
              if(cBuffer != '\0')
              if(cBuffer != 'ÿ')
              {
                asText += cBuffer;
    
                if(iUpdatePos % 1000 == 0)
                  FormMain->ProgressBar->Position = ftell(file);
    
                iUpdatePos++;
              }
            }
            while(!feof(file));
    
            fclose(file);
    
            FormMain->ProgressBar->Position = sr.Size;
          }
    


  • nebel,
    damit aktualisierst Du die Anzeige per Definition alle 1000 Zeichen, also etwa nach jedem KB. Das wird in den meisten Fällen gut funktionieren. Bei einer 1 MB großen Datei aktualisierst Du die Status-Anzeige also ca. 1000 mal. Daß das viel zu oft ist, geht wegen der hohen Rechengeschwindigkeit unter. (Es sei denn, Deine Progressbar ist 1000 Pixel breit :))

    Kleiner Modifikations-Vorschlag für Anzeige in 1%-Schritten:

    ...
    int step = sr.Size / 100;
    ...
    do
    {
    ...
        if(iUpdatePos % step == 0)
                  FormMain->ProgressBar->Position = ftell(file); 
    ...
    


  • Wenn du statt while eine for-Schleife benutzt (die Dateigrösse hast du ja ermittelt) dann kannst du auch noch auf das ftell verzichten und stattdessen den Schleifenzähler verwenden. Ausserdem sparst du dir so ggf. auch die iUpdatePos-Variable.

    Und evtl. wäre es besser, wenn du die Progressbar und das Intervall proportional zur Dateigrösse einstellst, so dass du unabhängig von der Dateigrösse immer mit z.B. zehn Schritten in der Anzeige auskommst.

    Eines steht jedenfalls fest, das Einlesen Zeichen für Zeichen ist immer langsamer als das Einlesen einer grossen Datenmenge am Stück (wie z.B. per fread). Vielleicht solltest du letzteres doch mal im Zusammenhang mit einem Timer und ftell ausprobieren.
    Oder du benutzt, ähnlich wie oben angedeutet, fread zum Einlesen proportionaler Dateiabschnitte (z.B. je 10%) und aktualiserst danach jeweils die ProgressBar.



  • @dschensky
    ich habs mal versucht. da kommt dann bei leeren dateien (ja sowas gibts auch ;)) ein "division durch null"-fehler

    @Jansen
    wie soll das aussehn, mit der for-schleife?
    for(int i = 0; i < feof(file); i++) <-- geht ja schlecht, oder?



  • i < sr.Size !?



  • ups 😃
    war nur ein test 😉

    also habs mal probiert und das gaze sieht jetzt so aus:

    FormMain->ProgressBar->Max = sr.Size; 
    
            for(int i = 0; i < sr.Size; i++)// datei stückchenweise einlesen
            {
              Application->ProcessMessages();
              cBuffer = fgetc(file);
    
              // ohne die zeichen
              if(cBuffer != '\0')
              if(cBuffer != 'ÿ')
              {
                asText += cBuffer;
    
                if(i % 4096 == 0) // update alle 4 kbs
                  FormMain->ProgressBar->Position = i;
              }
            }
            FormMain->ProgressBar->Position = sr.Size;
    

    also ich denk jetzt mal, dass das ftell nicht die "bremse" ist, sondern der progressbar. je öfter ich den update, desto langsamer wird das ganze. deswegen hab ich das mal auf 4 kb gebracht. jetzt bin ich schon bei 15 sekundne vom einlesen meines testordners, war vorher bei knapp ner minute. also schon ne besserung 😉



  • nebel schrieb:

    @dschensky
    ich habs mal versucht. da kommt dann bei leeren dateien (ja sowas gibts auch ;)) ein "division durch null"-fehler

    Also sowas sollte man eigentlich gesetzlich verbieten! 😡



  • was?
    leere dateien oder division durch null? 😉



  • nebel schrieb:

    was?
    leere dateien oder division durch null? 😉

    Beides !


Anmelden zum Antworten