AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte CSV-Reader. Schnelles lesen von CSV-Dateien

CSV-Reader. Schnelles lesen von CSV-Dateien

Ein Thema von alzaimar · begonnen am 11. Mär 2008 · letzter Beitrag vom 28. Nov 2017
Antwort Antwort
Seite 2 von 5     12 34     Letzte » 
alzaimar
Registriert seit: 6. Mai 2005
Hallo,

Ich habe mal eine Klasse geschrieben, die CSV-Dateien einliest und die einzelnen Elemente extrahiert. Dabei werden auch in '"' eingeschlossenen Strings korrekt erkannt.

Verwendet wird es so:
Delphi-Quellcode:
Var
  csvReader : TCSVReader;
  sData : TFileStream;

Begin
  sData := TFileStream.Create('Sample.CSV',fmOpenRead);
  csvReader := TCSVReader.Create (sData, ';');
  csvReader.First; // Nach Änderung auf Veranlassung von Grenzgaenger nun notwendig. Dank an 'deadcandance'
  Try
    While not csvReader.Eof Do Begin
      For i:=0 to csvReader.ColumnCount - 1 Do
        Memo.Lines.Add (csvReader.Columns[i]);
      csvReader.Next;
    End;
  Finally
    csvReader.Free;
    sData.Free;
  End;
End;
Es ist ziemlich flott. Vielleicht kann Jemand etwas damit anfangen.

Bugreports und Verbesserungsvorschläge sind natürlich erwünscht.

Bug: Grenzgaenger hat mich auf einen Fehler in der Behandlung von '""' aufmerksam gemacht. Weiterhin wünschte er sich den Quote-Character als Eigenschaft. Bitte sehr.
Erweiterung: ralfschwalbe hätte gern, das die Klasse auch mit UNIX-Umbrüchen umgehen kann. Bitte sehr.
Erweiterung: Noch besser: Man kann nun das EOL-Zeichen und die Länge selbst angeben (z.B. für Unix #10 und 1, Windows: #13 und 2)
Änderung: Laut grenzgaenger hat der Aufruf von 'First' im Konstruktor nix zu suchen. Recht hat er!
Bug: Kater Karlo hat einen Fehler im Konstruktor entdeckt, der bei Streams auftritt, deren Position>0 ist. Weiterhin ist ein überflüssiges privates Feld entfernt worden.
Angehängte Dateien
Dateityp: pas cscsv_785.pas (6,8 KB, 1993x aufgerufen)
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
 
alzaimar

 
Delphi 2007 Enterprise
 
#11
  Alt 13. Mär 2008, 09:33
Zitat von Union:
Naja, vielleicht machen das manche Programme so mit dem ListSeparator.
EXCEL macht das so... Aber echt interessant (auch der Wiki-Artikel). Ich dachte, CSV hätte sich MS 1923 ausgedacht. So lange kenn ich das jedenfalls (ungefähr, mein Gedächtnis )
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

 
Delphi 7 Enterprise
 
#12
  Alt 13. Mär 2008, 09:40
Jedenfalls ist Deine Lösung gut und praktikabel. Eigentlich geht es ja nicht um die Therorie, sondern dass man es für bestehende "CSV"-Definitionen verwenden kann. Ich bin auch erst vor kurzem darauf gekommen, als ich zum Debuggen eine "CSV" mit Semikolon ausgegeben habe und der Microsoft LogParser das Format nicht erkannte. Die nennen das dann TSV mit Delimiter =";".
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#13
  Alt 13. Mär 2008, 09:45
Zitat von Union:
Jedenfalls ist Deine Lösung gut und praktikabel.

Zitat von Union:
Die nennen das dann TSV mit Delimiter =";".
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

 
Delphi 7 Enterprise
 
#14
  Alt 13. Mär 2008, 10:26
Und wenn Du noch
SetString(Result, spFirst, spLen); ersetzt mit
Delphi-Quellcode:
SetLength(result, spLen);
Move(spFirst^, result[1], spLen);
dann wird das auch schnell
  Mit Zitat antworten Zitat
deadcantdance

 
Delphi 2007 Professional
 
#15
  Alt 12. Dez 2008, 14:02
Kleiner Hinweis. Das o.g. Bespiel funktioniert so nicht ganz.

Beim ersten Durchlauf ist ColumnCount = 0, erst nach dem Aufruf von csvReader.Next wird ColumnCount gesetzt.

Sollte doch dann eigentlich so sein:

Delphi-Quellcode:
Try
  if not csvReader.Eof then
    csvReader.Next;
  While not csvReader.Eof Do Begin
    For i:=0 to csvReader.ColumnCount - 1 Do
      Memo.Lines.Add (csvReader.Columns[i]);
    csvReader.Next;
  End;
Finally
  csvReader.Free;
  sData.Free;
End;
Ansonsten,

Viele Grüße,
deadcantdance
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#16
  Alt 14. Dez 2008, 19:50
In der kleinen Demo fehlt der Aufruf von 'csvReader.First'. Habe ich nachgetragen (siehe Eingangspost).
  Mit Zitat antworten Zitat
Kater Karlo

 
Delphi 2010 Professional
 
#17
  Alt 7. Jan 2009, 11:29

Hi,

ggf. ist es sinnvoll im Constructor vor dem Read die Position des zu lesenden Stream auf Null zu setzen.
Es sei denn es ist beabsichtigt erst ab der aktuellen Stelle einzulesen.

Die Variable fReader: TReader; kann weggelassen werden.

Gruss Kater Karlo
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#18
  Alt 7. Jan 2009, 11:54
Hallo Kater Karlo,

Es ist üblich, das der Aufrufer den Stream an die geeignete Stelle setzt, das muss er bei Verwendung anderer Komponenten (z.B. Crypter/Packer-Streams) auch selbst machen. Bei Instantiierung eines TFileStreams ist die Position eh bei 0.

Bezüglich deines Einwands mit dem Buffer fällt auf, das im Konstruktor ein kleine Ungenauigkeit auftritt, wenn die Position des Streams > 0 ist (wie du richtig bemerkt hast). Das sollte nun behoben sein.

Danke für die Anregungen
  Mit Zitat antworten Zitat
Kater Karlo

 
Delphi 2010 Professional
 
#19
  Alt 7. Jan 2009, 13:46
Hallo alzaimar,

ich hätte da noch einige Anregungen:

- Als Eigenschaft den Index der aktuellen Zeile
- Als Eigenschaft die aktuelle Zeile als String
- Veröffentlichen der Column-Information TStringPos

Extended:
- Erkennen von Kommentarzeilen (Zeile beginnt mit # oder über eine Eigenschaft bekannt zugebene Zeichenfolge)

MfG

Kater Karlo
  Mit Zitat antworten Zitat
ekoplayer
 
#20
  Alt 22. Feb 2009, 20:04
Kann mir einer vielleicht sagen wie ich beide die Datei zum laufen kriege?

Wenn ich sie abspeichern will sagt er mir immer Declaration of class TForm1 is missing or incorrect.

Und bei der zweiten Datei hinterlegt er das

Delphi-Quellcode:
  
csvReader : TCSVReader;
sData : TFileStream;
rot wenn ich es Compilieren will. kann mir wer helfen?
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf