Einzelnen Beitrag anzeigen

gemy

Registriert seit: 17. Feb 2019
34 Beiträge
 
#1

TStreamReader & TFileStream freeze nach laden von 140k Zeilen in Record.

  Alt 19. Sep 2021, 21:21
Guten Abend!

Ich lade eine Textdatei mit 140.000 Zeilen die so aufgebaut ist in ein Record:


Code:
2020.01.17,03:55,13476.49000,13476.74000,13471.74000,13472.74000,56
Das ist eine "Kerze" vom Dax (Also Datum, Uhrzeit, Open, High, Low, Close, Volumen)

Das Record sieht so aus:

Code:
type
  Tcandleprice = (sopen, slow, shigh, sclose);
  Tcandle = record
    sdate: string[20];
    stime: string[5];
    candleprice: array [Tcandleprice] of word;
    ivolume: integer;
  end;
  Tcandles = array of Tcandle;

Ich lad auch alle Zeilein erfolgreich in das Record, aber am Ende nachdem ich den TstreamReader oder den Tfilestream freigebe hängt das Programm circa 10 Sekunden lang. Sogar der Delphi Debugger hängt wenn man auf das rote Viereck für Stop drückt. Andere Programm lassen sich auch nicht in den Vordergrund bringen. Während er gerade die Datei lädt, kann ich nichtmal hier in das Forum Fenster klicken (wo ich gerade diesen Text schreibe).

Die Zeilen werden aber alle erfolgreich eingelesen. Aber warum dauert das am Ende noch so lange ?


Hier habe ich einen vereinfachten Code und auch dieser macht 10 Sekunden Pause am Ende.


Code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
type
  Tcandleprice = (sopen, slow, shigh, sclose);
  Tcandle = record
    sdate: string[20];
    stime: string[5];
    candleprice: array [Tcandleprice] of word;
    ivolume: integer;
  end;
  Tcandles = array of Tcandle;

var
  Form1: TForm1;
  candles: Tcandles;
implementation

{$R *.dfm}




procedure TForm1.Button1Click(Sender: TObject);
var
  filename: string;
  sr: TStreamReader;
  sl: TStringList;
  total, blocksize: integer;
  i, anzahlkerzen: integer;
  sepstring: char;
  aline: string;
begin
  anzahlkerzen :=0;
  Sepstring := FormatSettings.DecimalSeparator;
  filename := '[DAX30]5.csv';
  sl := TStringList.Create;
  sr := TStreamReader.Create(filename, true);
  sl.Capacity := sr.BaseStream.Size div 100;
  total := 0; // Total number of lines in the file (after it is read in)
  blocksize := 10000; // The number of lines per "block"
  try
    sl.BeginUpdate;
    try
      while not sr.EndOfStream do
        begin
          sl.Clear;
          while not (sl.Count >= blocksize) do
            begin
              sl.Add(sr.ReadLine);
              total := total + 1;
              if (sr.EndOfStream = true) then break;
            end;
          // Handle the current block of lines here
          for i := 0 to sl.Count-1 do
          begin
            SetLength(candles, Length(candles)+1);
            aline := sl[i];
            candles[AnzahlKerzen].sdate := Copy((aline), 1, Pos(',',(aline))-1);
            Delete(aline, 1, Pos(',', (aline)));
            candles[AnzahlKerzen].stime := Copy((aline), 1, Pos(',', (aline))-1);
            Delete(aline, 1, Pos(',', (aline)));
            candles[AnzahlKerzen].candleprice[sopen] := StrtoInt(StringReplace(Copy((aline), 1, Pos(',', (aline))-7),'.', sepstring,[]));
            Delete(aline, 1, Pos(',', (aline)));
            candles[AnzahlKerzen].candleprice[shigh] := StrToInt(StringReplace(Copy((aline), 1, Pos(',', (aline))-7),'.', sepstring,[]));
            Delete(aline, 1, Pos(',', (aline)));
            candles[AnzahlKerzen].candleprice[slow] := StrToInt(StringReplace(Copy((aline), 1, Pos(',', (aline))-7),'.', sepstring,[]));
            Delete(aline, 1, Pos(',', (aline)));
            candles[AnzahlKerzen].candleprice[sclose]:= StrToInt(StringReplace(Copy((aline), 1, Pos(',', (aline))-7),'.', sepstring,[]));
            Delete(aline, 1, Pos(',', (aline)));
            candles[AnzahlKerzen].ivolume := StrToInt(aline);
            inc(AnzahlKerzen);
            if anzahlkerzen mod 9999 = 9998 then memo1.Lines.Add('durchgang');
            form1.Caption := 'Candle Bot - reading Candle Nr.:'+inttostr(AnzahlKerzen)+' from '+ ExtractFileName(filename);
          end;
        end;
    finally
      sl.EndUpdate;
    end;
  finally
    sr.free;
    sl.Free;
  end;


end;


Noch was, als ich noch unter Window7 programmiert habe, da war mit dem selben Programm das Problem nicht zu sehen. Nur mit Windows 10. Habe das auch schon auf einen Server geladen und auch dort macht es seine Pause.

Ich habe nun schon statt currency word genommen, string länge festgelegt, setlength weggelassen und anfangs festgelegt, aber das Programm macht immer eine 10 Sekunden Pause nachdem es alles eingelesen hat.

Woran liegt das?



PS: Hier habe ich einen Downloadlink, falls sich jemand erbarmen möchte (nur source mit csv datei)

https://www.file-upload.net/download...nlesen.7z.html

Geändert von gemy (19. Sep 2021 um 21:36 Uhr) Grund: download link hinzugefügt zum testsen
  Mit Zitat antworten Zitat