![]() |
Problem mit TFileStream.Seek ?
Meine letzte Frage (Geschwindigkeitsoptimierung) wurde bestens beantwortet. :thumb:
Nun habe ich ein anderes Problem, das Fragen aufwirft. :gruebel: Ich habe eine Routine, bei der ich blockweise die Daten aus einer Datei lese. Alles wunderbar, solange die Datei kleiner 1-2MB ist. Sind die Dateien größer ist die Geschwindigkeit unterschiedlich. Einmal wird alles fix ausgelesen (z.B. 5500 Durchläufe des unteren Codes in weniger als 1 Sekunde), beim nächsten mal dauert es ewig. Das heisst, wenn ich nach 10 Sekunden einen Haltepunkt setze, wurden erst ca 900 Durchläufe durchgeführt. :?: Hier ist die Record-Definition:
Delphi-Quellcode:
Hier die Routine:
TMessageBlockHeader = record
Address: cardinal; BlockLength: cardinal; TextLength: cardinal; NextBlockAddress: cardinal; end;
Delphi-Quellcode:
procedure xyz.GetData(address: cardinal; var MyStream: TStringStream);
var FFileHandle: TFileStream; BlockHeader: TMessageBlockHeader; block: TStringStream; Schleife : Cardinal; begin FFileHandle := TFileStream.Create('C:\test.bin', fmOpenRead or fmShareDenyNone); //fmShareDenyWrite); Schleife := 0; While True do begin if address = 0 then break; inc(Schleife); // zum Zählen der Durchläufe FFileHandle.Seek(address, soFromBeginning); FFileHandle.Read(BlockHeader, sizeof(BlockHeader)); if address = BlockHeader.Address then begin if (BlockHeader.TextLength > 0) and (BlockHeader.TextLength <= BlockHeader.BlockLength) then begin block := TStringStream.Create(''); try block.CopyFrom(FFileHandle, BlockHeader.TextLength); MyStream.WriteString(block.DataString); finally block.Free; end; // if ((BlockHeader.NextBlockAddress > 0) // and (BlockHeader.NextBlockAddress <= address)) then // break; address := BlockHeader.NextBlockAddress; end; end; // if end;//while MessageBox(0, PChar('Schleifen: ' + IntToStr(Schleife)), 'Caption', MB_OK + MB_ICONINFORMATION); end; // if if FFileHandle <> nil then FFileHandle.Free; end; Ich habe mal etwas gelesen, dass Seek nicht immer gleich arbeitet. Was kann man dagegen tun? Danke für jede Hilfe. Ich hoffe, mich kann jemand erleuchten :coder2: |
Re: Problem mit TFileStream.Seek ?
Zitat:
|
Re: Problem mit TFileStream.Seek ?
Naja, wenn es 1/10 Sekunde Abweichung wäre, hätte ich nichts dagegen.
Aber nach 10 Sekunden nur 1/5 des Lesens geschafft, wo er ab und zu nur ein paar Zehntel benötigt? |
Re: Problem mit TFileStream.Seek ?
schon mal mit TMemoryStream probiert?
|
Re: Zeitproblem mit TStringStream.WriteString ?
Hallo,
mir hat das Problem keine Ruhe gelassen. Jetzt habe ich Zeitmessungen in fast jeder Zeile des Quelltextes durchgeführt. Und es ergab sich, dass das Problem nicht an TFileStream liegt (lag im 100stel Sekunden-Bereich) sondern an TStream.WriteString. Dies klaut mir die Zeit...
Delphi-Quellcode:
Sieht irgendjemand eine andere Möglichkeit, wie ich die Daten schnell in den StringStream bekomme?
try
block.CopyFrom(FFileHandle, BlockHeader.TextLength); MyStream.WriteString(block.DataString); finally block.Free; end; |
Re: Problem mit TFileStream.Seek ?
Und damit liegt es sicherlich am Memory-Manager. Beim Schreiben des Strings wird dieser erweitert. Dafür muss Speicher reserviert werden, was beim Überschreiten bestimmter Grenzen dauern kann. Das ist bei jeder Stream-Schreiboperation so, egal ob Memory, File usw.
Abhilfe: Die geschätzte maximale Größe anfänglich mit SetSize setzen. Am Ende der Verarbeitung mit SetSize(Position) wieder verkleinern. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:17 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