CSVParser.javajava.io.Reader und tokenisiert CSV-Daten Zeichen für Zeichen. Unterstützt quotierte Felder, eingebettete Zeilenumbrüche innerhalb quotierter Zellen, maskierte doppelte Anführungszeichen (""-Konvention), konfigurierbare Feldtrennzeichen, Spaltennamen-Mapping für Kopfzeilen und UTF-8-BOM-Erkennung. Geschrieben von Kai Reinhard und H. Spiewok (2005), älter als und ohne externe CSV-Bibliotheksabhängigkeiten.java.io.IOException / java.io.Reader — Zeichenstrom-Eingabejava.util.ArrayList, HashMap, List, Map — Ergebnis-Speicher und Spaltenindex für Kopfzeilenorg.apache.commons.lang3.StringUtils — Leerzeichen-Prüfung in Fehlermeldungenorg.slf4j.Logger — FehlerprotokollierungAnstatt Regex oder einen Parser-Generator zu verwenden, implementiert CSVParser einen zeichenweisen Lexer mit einem Pushback-Puffer. Dieses Design priorisiert Kontrolle über Fehlerbehandlung und Leistung für die spezifische Teilmenge der CSV-Formatierung, die von ProjectForge verwendet wird.
enum Type { EOF, EOL, CHAR }
Token-Typen: Dateiende (End-Of-File), Zeilenende (End-Of-Line) oder Zeichendaten. Dies steuert die Zustandsmaschine des Parsers.
int[] (pushbackBuffer) mit Indexverfolgung — ermöglicht Vorausschau und Rückverfolgung ohne Reader-Unterstützung für mark()/reset()\ncval für Zeichen-Token. Behandelt \r\n (Windows CRLF) als einzelnes EOL-TokenskipBOM() wird während der Konstruktion aufgerufen, um ein UTF-8-Byte-Order-Mark (\uFEFF) am Dateianfang zu erkennen und zu überspringen. Wenn keine BOM vorhanden ist, wird das erste Zeichen zurückgelegt (unread). Dies ermöglicht das korrekte Parsen von CSV-Dateien, die aus Microsoft Excel exportiert wurden, da diese für UTF-8-Dateien eine BOM enthalten.
Die Kern-CSV-Parsing-Logik behandelt diese Fälle:
| Fall | Verhalten |
|---|---|
| Unquotierte Zelle | Zeichen werden bis zum Trennzeichen oder Zeilenende gesammelt |
Quotierte Zelle ("...") | Zeichen innerhalb der Anführungszeichen werden gesammelt; Anführungszeichen müssen korrekt geschlossen sein |
Maskiertes Anführungszeichen ("") | Zwei aufeinanderfolgende doppelte Anführungszeichen innerhalb einer quotierten Zelle repräsentieren ein einziges literales Anführungszeichen |
| Eingebetteter Zeilenumbruch | Zeilenumbrüche innerhalb quotierter Zellen werden beibehalten (mehrzeilige Zellenwerte) |
| Nachgestelltes Leerzeichen | Leerzeichen nach dem schließenden Anführungszeichen werden übersprungen; erwartet als nächstes Trennzeichen oder Zeilenende |
| Nicht geschlossenes Anführungszeichen | Löst eine RuntimeException mit einer beschreibenden Fehlermeldung aus, die Zeilen-/Spaltennummer enthält |
Liest Zellen bis zum Zeilenende oder Dateiende und sammelt sie in einer List<String>. Gibt bei Dateiende null zurück (keine leere Liste — Aufrufer können Dateiende von leeren Zeilen unterscheiden).
Für CSV-Dateien mit einer Kopfzeile liest parseHeadCols() die erste Zeile und erstellt eine colMap: Map<String, Integer>, die Spaltennamen ihren Positionsindizes zuordnet. Nachfolgende Aufrufe von getCell(List<String>, spaltenname) rufen Werte nach Spaltenname statt nach Position ab. Dies ermöglicht einen Excel-ähnlichen Zugriff auf benannte Spalten.
Drei verschiedene Fehlerkonstanten bieten spezifische Diagnosen:
ERROR_UNEXPECTED_QUOTATIONMARK = "Unerwartetes Anführungszeichen \" (nur in quotierten Zellen erlaubt)." ERROR_QUOTATIONMARK_MISSED_AT_END_OF_CELL = "Anführungszeichen \" am Ende der Zelle fehlt." ERROR_DELIMITER_OR_NEW_LINE_EXPECTED_AFTER_QUOTATION_MARK = "Trennzeichen oder Zeilenumbruch nach Anführungszeichen erwartet." ERROR_UNEXPECTED_CHARACTER_AFTER_QUOTATION_MARK = "Unerwartetes Zeichen nach Anführungszeichen."
Jede Meldung wird über createMessage() um Zeilen- und Spaltennummern ergänzt.
CSVParser verwendet CSVWriter.DEFAULT_CSV_SEPARATOR_CHAR (';' — Semikolon) als Standardtrennzeichen. Dies ist die europäische CSV-Konvention (Microsoft Excel in deutschen Gebietsschemata verwendet semikolongetrennte CSV). Das Trennzeichen ist über setCsvSeparatorChar() konfigurierbar.
parseLine() liest eine Zeile und gibt alle Zellen zurück — geeignet für mittelgroße Dateien, aber nicht für sehr große (Multi-GB) CSVs868d6abb7 2025 -> 2026 161d71602 WIP: CSVParser: BOM-Zeichen. dfb2378df WIP: CSVParser: Mehrzeiler usw. 63081666f Quellcode-Dateiköpfe: 2024 -> 2025. a73905c14 Korrigiere Tippfehler in Verzeichnissen projectforge*/ Gefunden mittels codespell a72903e36 *.java, *.kt: StringBuffer -> StringBuilder. b6092df09 Copyright 2023 -> 2024 ab45d51fa Copyright 2001-2022 -> 2001-2023.