Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fortschritt Datei einlesen (https://www.delphipraxis.net/136824-fortschritt-datei-einlesen.html)

Linguini 8. Jul 2009 16:40


Fortschritt Datei einlesen
 
Hallo,

ich möchte Textdateien in einen String einlesen, und dann bestimmte Zeichenketten in diesem String ersetzen.
Das klappt auch soweit ganz gut, nur muss ich mir noch überlegen wie ich das ganze in eine Schleife einbaue falls die Zeichenkette öfters vorkommt.
Da das einlesen in einen String bei großen Textdateien dauert, möchte ich den Fortschritt am besten in einer Progressbar anzeigen lassen.
Nur wie mache ich das?
Bisher lese ich die Textdateien so ein:

Delphi-Quellcode:
function File2String(FileName: ansistring): ansistring;
var
 MyStream: TFileStream;
 MyString: ansistring;
begin
 MyStream := TFileStream.Create(FileName, fmOpenRead
   or fmShareDenyNone);
 try
   MyStream.Position := 0;
   SetLength(MyString, MyStream.Size);
   MyStream.ReadBuffer(Pointer(MyString)^, MyStream.Size);
 finally
   MyStream.Free;
 end;
 Result := MyString;
end;
Funktion hab ich von exemod geklaut. ;)

Ich möchte nun den Fortschritt des Einlesevorgangs in einer Progressbar darstellen.
Nur wie?

Danke

Looper 8. Jul 2009 16:54

Re: Fortschritt Datei einlesen
 
Eine Variante:
Du lädst die Datei blockweise (z.B. in 50er Schritten) und lädst den String in einer Schleife. In jedem Schleifendurchlauf musst du eine ProgressBar erhöhen bzw. vorher noch die Property Max setzen.

Gruß Janek

Linguini 8. Jul 2009 17:14

Re: Fortschritt Datei einlesen
 
Blockweise dann mit ReadBlock?
Kannst du mir dazu vielleicht ein kleines Beispiel geben =)

SirThornberry 8. Jul 2009 17:32

Re: Fortschritt Datei einlesen
 
nen, nicht readblock. Du liest derzeit die ganze Datei in einem rutsch.
Delphi-Quellcode:
MyStream.ReadBuffer(Pointer(MyString)^, MyStream.Size);
und anstelle gleich MySteam.Size zu lesen sollst du einfach in kleinen Stücken lesen. Ist deine Datei Beispielsweise derzeit 5 MB groß list du diese mit diesem einen Aufruf ein.
Du könntest aber auch einfach 5 mal ein MB lesen (dann nämlich nicht MyStream.size als Anzahl der zu lesenden Bytes sondern 1024 * 1024) und das solange wie noch Daten vorhanden sind.
Also wie im richtigen Leben wo man sich auch nicht das ganze Brot mit einemal in den Mund schiebt sondern Scheibe für Scheibe nimmt bis es alle ist.

Ruio 8. Jul 2009 19:35

Re: Fortschritt Datei einlesen
 
Und was macht man, wenn der zu ersetzende String gerade an der Trennstelle ist und nicht erkannt wird?

p80286 9. Jul 2009 13:46

Re: Fortschritt Datei einlesen
 
@Ruio

Das Suchen und Ersetzen erfolgt erst wenn alles in einen String eingelesen ist.

Ansonsten läßt du den Index Deines Puffers bis Puffer[maxPuff-(wortlaenge-1)] laufen, schiebst die restlichen Chars nach vorne und liest dann wieder ein. Dafür sollte der Puffer aber schon recht groß sein, sonst beschäftigt Dein Programm sich nur mit Datenschieben.

@Sir Thornberry

Das hätte ich gerne mal als Source gesehen, denn irgendwie muß der Ergebnisstring doch zusammengestückelt werden.
Mein Vorschlag:
Delphi-Quellcode:
 MyFile : text;

 { einen ordentlichen Buffer mit settextbuf nicht vergessen!}
....
repeat
  readln(MyFile,Satz);
  ergSatz:=Ergsatz+Satz;
  progressbar.step;
until eof(Myfile);
....
sollte zwar funktionieren, aber ist bestimmt keine Performancespitze.

Gruß
K-H

p80286 9. Jul 2009 15:12

Re: Fortschritt Datei einlesen
 
Ich hab mal ein wenig gebastelt:
Delphi-Quellcode:
const
  rZ=1024;
var
  p      : integer;
  ds     : string;
  fs     : tfilestream;
  gelesen : integer;
begin
  fs:=tfilestream.Create('c:\temp\Testdatei.txt',fmOpenRead or fmShareDenyNone);
  p:=1;
  setlength(ds,fs.size);
  repeat
    gelesen:=fs.Read(ds[p],rz);
    inc(p,gelesen);
    progressbar1.stepit;
  until gelesen<rz;
  fs.Free;
  p:=1;
  repeat
    p:=posex('@@',ds,p);
    if p>0 then begin
      ds[p]:='#';
      ds[p+1]:='#';
    end;
  until p<1;
  label1.Caption:=ds;
end;
funktionieren tut's, aber da kann noch einiges optimiert werden.
(z.B. rz=102400)

Gruß
K_H


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz