Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   CSV-Reader. Schnelles lesen von CSV-Dateien (https://www.delphipraxis.net/110025-csv-reader-schnelles-lesen-von-csv-dateien.html)

alzaimar 10. Aug 2009 07:38

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo Jan,
Das von Dir beschriebene Datenformat (konstante Spaltenbreite) sind nicht nur keine CSV-Datei "im eigentlichen Sinne", sondern überhaupt nicht.

Um Daten mit konstanter Spaltenbreite zu importieren, sollte sich ein anderer Reader implementieren lassen, der dies wesentlich eleganter und vor allem performanter lösen kann: Er benötigt ja nur die Spaltenbreite, den linken Abstand sowie optional ein Füllzeichen. So ein Reader funktioniert intern völlig anders als ein CSV-Reader, wieso sollte man also einen CSV-Reader dafür 'aufwerten' (ich würde das eher 'verwässern' nennen)? Eine Klasse sollte genau einem Zweck dienen (hier: Lesen von CSV-Dateien).

Zudem sollte man Klassen auch nicht mit Eigenschaften ausstatten, deren Funktionalität sich mit wenigen Aufrufen der Elementaroperationen selbst nachbilden lässt:

Nur leere Zellen am Anfang der Zeile ignorieren:
Delphi-Quellcode:
Var
  bAtBeginningOfLine : Boolean;
  iRealColumn : Integer;
  sCellData : String;
...
csvReader.First;
While not csvReader.Eof Do Begin                                          
  bAtBeginningOfLine := True;
  iRealColumn := 0;
  For i := 0 to csvReader.ColumnCount - 1 Do Begin
    sCellData := csvReader.Columns[i];
    If bAtBeginningOfLine And (sCellData = '') Then Continue;
    bAtBeginningOfLine := False;
    inc (iRealColumn); // Die 'Spaltennummer' ohne leere Zellen am Anfang
    Memo.Lines.Add (sCellData);
  End;
  csvReader.Next;                                                        
End;
Leere Zellen ignorieren:
Delphi-Quellcode:
Var
  iRealColumn : Integer;
  sCellData : String;

...
csvReader.First;
While not csvReader.Eof Do Begin                                          
  iRealColumn := 0;
  For i := 0 to csvReader.ColumnCount - 1 Do Begin
    sCellData := csvReader.Columns[i];
    If sCellData = '' Then Continue;
    inc (iRealColumn); // Die 'Spaltennummer'
    Memo.Lines.Add (sCellData);
  End;
  csvReader.Next;                                                        
End;
Die OOP-konforme Vorgehensweise hier (für Dich) wäre so:
1. Definieren einer abstrakten Basisklasse ("TableReader"), die die elementaren Operationen zum Lesen von Daten aus Dateien bereitstellt (First, ColumnCount, Next, Eof, Columns).
2. Umschreiben der Klasse CSV-Reader als Nachfolger des "TableReader".
3. Implementieren der Klasse "Constant-Column Reader" als Nachfolger des "TableReader".

Du kannst nun auch weitere 'TableReader' implementieren, z.B. die eine SYLK-Datei einlesen, oder direkt mit BIFF arbeiten, oder XML, JSON etc. Der Vorteil ist, das Du diverse schlanke, wartbare und performante Klassen hast, die ohne Probleme erweiterbar und optimierbar sind. Bei einer eierlegenden Wollmilchsauklasse ("God Class") ist dies nicht der Fall.

Gruß zurück.

Triple Crown 7. Sep 2011 13:25

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo!

Vielen Dank für die Unit!!!

Hat bei mir mit
WIN 7 /Lazarus 0.9.30/ FPC 2.4.2
geklappt.

Gruß!
Andreas

Monday 29. Aug 2012 12:49

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hi,

funktioniert super! Danke! Selbst große Datenmenge packt der Reader in kürzester Zeit!

LG

divBy0 17. Jan 2013 13:49

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo,
ich stehe gerade auf dem Schlauch. Die CSV-Datei ist ANSI-kodiert und wird unter XE2 als asiatischer Schriftzeichensalat gelesen.
Hab die Datei schon mit TEncoding nach Unicode, UTF8 und UTF16 konvertiert, bringt mich aber alles nicht weiter.

Kann mich mal bitte jemand in die richtige Richtung schubsen?

p80286 17. Jan 2013 14:57

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Ich hab die Sourcen gerade nicht zur Hand, aber das hört sich an als ob eine Unterscheidung String/Ansistring fällig wäre.

Gruß
K-H

roadrunner-S51 3. Jul 2014 10:05

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Sorry das ich das alte Thema nochmal ausgrabe, aber ich habe das selbe Problem mit den Unicodeformat und hätte gern gewusst, ob mittlerweile eine Lösung existiert...

Dejan Vu 3. Jul 2014 11:19

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Na ja. Der Code geht davon aus, das ein Char genau ein Byte lang ist. Das muss man nur umschreiben/anpassen.

roadrunner-S51 3. Jul 2014 11:40

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
OK, aber genau da steh ich gerade etwas auf dem Schlauch... Hat da jemand vielleicht ein Beispiel oder ähnliches für mich?

Sherlock 3. Jul 2014 12:33

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Eigentlich geht der Code von PChar als einzelnem Zeichen aus. Unter den Delphis ab...ähm...2009? ist das nunmal PWideChar und nicht PAnsiChar. Eventuell sollte die "Bytigkeit" von Zeichen als weiterer Parameter hinzugefügt werden (was den Code nicht wirklich verschlanken würde). Wenn man aber seinen Anwendungsfall genau kennt, dürfte ein explizites Ersetzen sämtlicher PChar durch PAnsiChar die ursprüngliche ANSI-Funktionalität gewährleisten.

Sherlock
(für den dieses "Problem" nur wieder zeigt wie unsinnig es ist einem "Standard"-Typen von Version zu Version andere Basistypen zu verpassen)

Dejan Vu 3. Jul 2014 12:44

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Grob gesehen, fast alle '1' mit 'OneChar' und alle '2' mit 'TwoChar' ersetzen, wobei die beiden Symbole entweder Konstanten sind, die über die Compilerversion mit 1/2 oder 2/4 vorbelegt werden, oder eben als Properties.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:12 Uhr.
Seite 4 von 5   « Erste     234 5      

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