CSVParser.javajava.io.Reader et tokenise les données CSV caractère par caractère, prenant en charge les champs entre guillemets, les sauts de ligne intégrés dans les cellules entre guillemets, les guillemets doubles échappés (convention ""), les séparateurs de champ configurables, le mappage des noms de colonnes d'en-tête et la détection BOM UTF-8. Écrit par Kai Reinhard et H. Spiewok (2005), il est antérieur et évite les dépendances externes de bibliothèque CSV.java.io.IOException / java.io.Reader — Entrée de flux de caractèresjava.util.ArrayList, HashMap, List, Map — Stockage des résultats et indexation des colonnes d'en-têteorg.apache.commons.lang3.StringUtils — Vérification de chaîne vide dans les messages d'erreurorg.slf4j.Logger — Journalisation des erreursPlutôt que d'utiliser des expressions régulières ou un générateur d'analyseur, CSVParser implémente un analyseur lexical caractère par caractère avec un tampon de réinjection. Cette conception privilégie le contrôle sur la gestion des erreurs et les performances pour le sous-ensemble spécifique de formatage CSV utilisé par ProjectForge.
enum Type { EOF, EOL, CHAR }
Types de jetons : Fin de fichier, Fin de ligne ou données de caractère. Cela pilote la machine à états de l'analyseur.
int[] de 5 éléments (pushbackBuffer) avec suivi d'index — permet l'anticipation et le retour en arrière sans support Reader pour mark()/reset()\ncval pour les jetons de caractère. Gère \r\n (CRLF Windows) comme un seul jeton EOLskipBOM() est appelée lors de la construction pour détecter et ignorer un marqueur d'ordre d'octets UTF-8 (\uFEFF) au début du fichier. Si aucune BOM n'est présente, le premier caractère est réinjecté (unread). Cela permet une analyse correcte des fichiers CSV exportés depuis Microsoft Excel, qui inclut une BOM pour les fichiers UTF-8.
La logique principale d'analyse CSV gère ces cas :
| Cas | Comportement |
|---|---|
| Cellule sans guillemets | Les caractères sont accumulés jusqu'au séparateur ou à la fin de ligne |
Cellule entre guillemets ("...") | Les caractères entre guillemets sont accumulés ; les guillemets doivent être correctement fermés |
Guillemet échappé ("") | Deux guillemets doubles consécutifs dans une cellule entre guillemets représentent un caractère de guillemet littéral |
| Saut de ligne intégré | Les sauts de ligne dans les cellules entre guillemets sont conservés (valeurs de cellule multilignes) |
| Espace blanc final | Les espaces blancs après le guillemet fermant sont ignorés ; attend un séparateur ou une fin de ligne ensuite |
| Guillemet non fermé | Lève une RuntimeException avec un message d'erreur descriptif incluant le numéro de ligne/colonne |
Lit les cellules jusqu'à la fin de ligne ou la fin de fichier, en les collectant dans une List<String>. Renvoie null à la fin du fichier (pas une liste vide — les appelants peuvent distinguer la fin du fichier des lignes vides).
Pour les fichiers CSV avec une ligne d'en-tête, parseHeadCols() lit la première ligne et construit une colMap : Map<String, Integer> mappant les noms de colonnes à leur index positionnel. Les appels ultérieurs à getCell(List<String>, nomcolonne) récupèrent les valeurs par nom de colonne plutôt que par position. Cela permet un accès aux colonnes nommées à la manière d'Excel.
Trois constantes d'erreur distinctes fournissent des diagnostics spécifiques :
ERROR_UNEXPECTED_QUOTATIONMARK = "Guillemet inattendu \" (uniquement autorisé dans les cellules entre guillemets)." ERROR_QUOTATIONMARK_MISSED_AT_END_OF_CELL = "Guillemet \" manquant à la fin de la cellule." ERROR_DELIMITER_OR_NEW_LINE_EXPECTED_AFTER_QUOTATION_MARK = "Délimiteur ou nouvelle ligne attendu après le guillemet." ERROR_UNEXPECTED_CHARACTER_AFTER_QUOTATION_MARK = "Caractère inattendu après le guillemet."
Chaque message est enrichi des numéros de ligne et de colonne via createMessage().
CSVParser utilise CSVWriter.DEFAULT_CSV_SEPARATOR_CHAR (';' — point-virgule) comme séparateur par défaut. C'est la convention CSV européenne (Microsoft Excel dans les paramètres régionaux allemands utilise le CSV délimité par des points-virgules). Le séparateur est configurable via setCsvSeparatorChar().
parseLine() lit une ligne et renvoie toutes les cellules — adapté aux fichiers de taille modérée mais pas aux très gros CSV (plusieurs Go)868d6abb7 2025 -> 2026 161d71602 WIP : CSVParser : caractères BOM. dfb2378df WIP : CSVParser : multilignes etc. 63081666f En-têtes de fichiers source : 2024 -> 2025. a73905c14 Correction de fautes de frappe dans les répertoires projectforge*/ Trouvé via codespell a72903e36 *.java, *.kt : StringBuffer -> StringBuilder. b6092df09 Copyright 2023 -> 2024 ab45d51fa Copyright 2001-2022 -> 2001-2023.