Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Progressbar beim Einlesen einer CSV-Datei


colaka - Mi 31.12.08 12:04
Titel: Progressbar beim Einlesen einer CSV-Datei
Hallo,

ich möchte CSV-Dateien in eine Paradoxtabelle einlesen. Da es sich um relativ große Dateien handelt, möchte ich den Fortschritt in einer Progressbar darstellen. Das Ganze mache ich mit dem folgenden Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure TForm1.Button2Click(Sender: TObject);
var
  d : Textfile;
  Zeile, Feldname, TextTemp : String;
  i, Z : Integer;
begin
  OpenDialog.Execute;
  TableTemp.DatabaseName := ExtractFilePath(ParamStr(0));
  TableTemp.TableName := 'TTemp.DB';
  TableTemp.CreateTable;
  TableTemp.Active := true;
  assignFile(d, OpenDialog.FileName);
  Reset(d);                   // Datei öffnen
  Progressbar.Position := 0;
  Progressbar.Max := FileSize(d);
  Label2.Caption := IntToStr(Progressbar.Max);
  while not EOF(d) do
  begin
    ReadLn(d,Zeile);
    Z := SizeOf(Zeile);
    TableTemp.Append;
    for i := 1 to 20 do
      begin  // CSV-Liste wird in TableTemp eingelesen
      Feldname := 'Feld'+IntToStr(i);
      TextTemp := copy(Zeile, 0, (POS(';', Zeile)));
      TableTemp.FieldByName(Feldname).AsString :=  copy(TextTemp, 1, length(TextTemp)-1);
      Zeile := copy(Zeile, length(TextTemp)+1, (length(Zeile)-length(TextTemp)));
      end;
      Progressbar.Position := Progressbar.Position + Z;
      Label3.Caption := IntToStr(Progressbar.Position);
      TableTemp.Post;
    end;
  closeFile(d);
end;


Leider zeigt mir die Progressbar nur etwa 75% an, wenn die CSV-Datei bereits vollkommen eingelesen ist. Also stimmt die Summe von SizeOf(Zeile) offenbar nicht mit dem Wert von FileSize(Datei) überein. Oder habe ich da irgendeinen Dankfehler?

Hat vielleicht jemand eine Idee, wie ich das anders oder besser lösen kann?

Danke Ebi

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


jaenicke - Mi 31.12.08 14:21

Lass dir bitte einmal den Wert von SizeOf ausgeben. ;-)
Der ist immer 4 (Delphi ist ja bis jetzt immer 32bittig, noch nicht 64), nämlich die Größe eines Pointers. Nichts anderes ist nämlich eine Stringvariable eigentlich.

Was du meinst ist Length, nämlich die Länge des enthaltenen Strings. Dazu kommt noch das oder die beiden (je nach Betriebssystem, für das die Datei war) Zeilenumbruchszeichen.

Besser geeignet dürfte die Funktion FilePos sein, die dir die aktuelle Position innerhalb einer Datei zurückgibt, das sollte denke ich auch bei einer Textdatei funktionieren. ;-)

// EDIT:
Ach ja: bei großen Dateien würde ich die Progressbar nicht bei jeder Zeile aktualisieren, das macht das ganze unnötigerweise deutlich langsamer.
Und zur Beschleunigung kann man ggf. auch noch weitere Optimierungen machen, deine Stringoperationen z.B. ;-).