|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Le format CSV est, aujourd'hui encore, largement utilisé. Il fait le bonheur des équipes de développement car il est simple à manipuler. La lecture d'un fichier au format CSV demande toutefois un certain nombre de compétences.
Je propose ici un article qui aborde les points clés à maîtriser, pas à pas avec une difficulté progressive, pour savoir traiter le célèbre CSV. Il y aurait beaucoup de choses à ajouter, notamment à propos des fichiers volumineux, mais l'essentiel est là pour bien commencer. L'article se trouve à l'adresse suivante : http://thierry-leriche-dessirier.dev...csv-avec-java/ Tous les commentaires, surtout ceux qui disent du bien et m'encouragent (lol), sont les bienvenus. Bonne lecture. |
|
30
|
|
|
#2 |
|
Membre émérite
![]() Inscription : septembre 2006 Messages : 708 ![]() |
Bonjour,
je n'ai pas été jusqu'en bas, mais ai été surpris de voir que Excel ne modifiait pas les fichiers .csv. Là où je travaille nous avons justement eu pas mal de problème avec des fichiers CSV ouverts avec Excel (2000 et 2003), où apparaissent subitement des guillemets autour des champs, où les dates changent de format, où des 0 deviennent des 0.0... Je ne sais pas ce qu'il en est d'Excel 2007 et 2010 mais il me semble important de le mentionner!
__________________
Veuillez agréer nos sentiments les plus distingués. Soyez assurés de notre entière collaboration, bien à vous pour toujours et à jamais dans l'unique but de servir l'espérance de votre satisfaction, dis bonjour à ton père et à ta mère, bonne pétanque, mets ton écharpe fais froid dehors. |
|
|
10
|
|
|
#3 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Effectivement je n'ai pas testé sur les vieilles versions d'Excel. Les captures ont été faites sur 2010. Du coup ma remarque sur Open office est peut-être également valable pour Excel 2003.
|
|
00
|
|
|
#4 |
|
Nouveau Membre du Club
![]() Thibaud Vibes Inscription : juin 2008 Messages : 13 ![]() |
Merci pour ce tuto complet sur les CSV.
Il est vrai que ces fichiers sont plus légers que des fichiers XML mais selon moi ils sont infiniment plus compliqués du fait de l'absence de règles. Prendre en compte tous les cas se révèle complexe comme le montre votre tutorial finalement (16 paragraphes quand même). Au moins avec le XML il y a les DTD ou les XSD qui permettent de vérifier l'intégrité du fichier avant la lecture. Toutes les applications proposent des export CSV mais jamais sous la même forme (séparateur duifférents, pas de protections, ...) et au final c'est pénible à intégrer. Combien d'imports plantent en plein milieu parce que notre parseur de fichier CSV ne prend pas tout en charge? Enfin, je trouve dommage que la notion d'encodage des caractères ne soit pas évoquée bien que la problématique soit plus large que la lecture de fichiers CSV. C'est très souvent une source de problèmes. Le code proposé n'est donc pas 100% portable (NB: je n'ai pas téléchargé le .zip) puisque les classes "bas niveau" utilisées pour lire le fichier vont s'appuyer sur l'encodage par défaut de la JVM. En tout cas j'espère que vos élèves sont sensibilisés, sinon j'imagine bien leur déconvenue lorsqu'ils reprendront vos sources pour lire un fichier CSV encodé en UTF-8, sous Windows... |
|
10
|
|
|
#5 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Effectivement l'article pourrait encore traiter un grand nombre de choses. Quand j'ai réalisé qu'il y avait autant de pages, j'ai reporté ces ajouts pour une prochaine version. J'avoue toutefois que je n'avais pas pensé à l'encoding.
Le format CSV possède un avantage sur le XML, c'est son poids. En effet, lorsqu'il y a des millions de lignes, ça fait une grosse différence. Dans tous les cas, avec les fichiers volumineux, on utilise des techniques qui ne sont pas présentées dans l'article. |
|
00
|
|
|
#6 | ||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 562 ![]() |
Code :
La méthode close() d'un stream ou d'un reader appelle automatiquement les méthods close() de ses enfants, conformément au pattern decorator. Donc vous ne devriez pas faire fr.close() car la ressource est déjà fermée et suivant les implémentations, vous pourriez vous manger une IOException. Par ailleurs votre boucle peut s'écrire Code :
Je lirai plus en détails ce soir ou demain. Citation:
La validation XSD est très coûteuse et bien souvent, elle ne permettra pas de se passer d'une validation métier "a mano". Et lire un gros fichier XML (de l'ordre des 500mo-1GB) est infiniment plus complexe que lire un gros fichier CSV. Citation:
Si vous intégrez ces règles, votre parseur peut facilement gérer 98% des sorties générées par d'autres produits. |
||||||
|
|
10
|
|
|
#7 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Attention aux fermetures des ressources. Si tu fermes le FileReader en espérant qu'il va automatiquement fermer le BufferedReader, que va-t-il se passer si ça plante ?... cf. bonnes pratiques de developpez... En outre, les codes de l'article sont volontairement tronckés pour des raisons de lisibilité. Vous avez sans doute remarqué l'absence de try-catch...
Pour le while, très bonne remarque. Le format CSV est définie par la RFC 4180. Toutefois on constate souvent des extensions communément admises. Il faut penser que les lecteurs CSV sont souvent écrits spécifiquement pour un format donné, de manière optimisée. Dans l'article, je m'amuse à deviner le format utilisé mais c'est juste un jeu. En vrai le format est connu d'avance. Dans l'article, je fais l'impasse sur plusieurs points. D'abord l'encoding mais c'est une blague. Ensuite les data multilignes avec détection des délimiteurs mélangés. Et surtout les fichiers volumineux. J'avais pensé faire un chapitre sur les accès concurrents, puisque j'utilise les CSV comme une base de données, mais en vrai ils doivent être utilisés pour de la transmission de données, et donc il n'y a pas de vrai sujet de concurrence ou de mise-à-jour. Quand à la validation, qu'en dire. Ca dépend un peu de l’émetteur du flux. En général, je zappe carrément la phase de validation. C'est trop couteux. Si ça se passe mal, je lance un roll back. |
|
00
|
|
|
#8 |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 562 ![]() |
Lol c'est le contraire. Vous laissez le BufferedReader fermer le FileReader. Le BufferedReader possède une instance de FileReader, pas l'inverse.
|
|
|
00
|
|
|
#9 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Jeu oui pardon, je voulais dire l'inverse. Bref si tu le laisses faire, et que ça se passe mal, tu risque d'avoir des ressources non fermées, voire pire mal fermées. Il y a d'ailleurs des implémentations de la jvm qui ne sont pas très propres la dessus. Je crois qu'on en a beaucoup parlé à l'arrivée de java 7.
|
|
00
|
|
|
#10 | |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 562 ![]() |
Citation:
S'il échoue en appelant la méthode close() du FileReader, vous n'aurez pas plus de chance que lui. Par ailleurs une exception à la fermeture d'une ressource est quasi-systématiquement lié à une exception précédente (style une exception se déclenche dans votre code de lecture/écriture et la ressource devient instable, puis votre finally appelle courageusement close() qui échoue à son tour, cette deuxième erreur est ingérable et sauf cas extrême on la supprime afin qu'elle n'occulte pas la première). |
|
|
|
00
|
|
|
#11 | ||
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Oui et non. Même si je ne suis pas complétement d'accord avec cette interprétation de la théorie, il ne faut pas oublier qu'en pratique, on est loin du compte, surtout avec des objets maison et/ou des jdk custom...
Dans tous les cas, ça ne mange pas de pain de fermer la ressource soit même quand on n'en a plus besoin. Le bon pattern serait quelque chose du style : Code :
Quoi que les ressources ne sont pas toutes logées à la même enseigne dans java 7 :-( Et c'est précisément pour une bonne raison. Devinez laquelle... |
||
|
00
|
|
|
#12 | |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 562 ![]() |
Citation:
![]() ![]() Je me demande si depuis le début on ne parle pas chacun d'une chose différente. J'attire juste ton attention sur le fait que lorsque tu appelles la méthode close() du bufferedReader, celle ci appelle la méthode close() du FileStream par convention. Et que par conséquent ton appel explicite à FileStream.close() a la suite a au mieux aucun effet, au pire génère une erreur car l'état de la ressource est déjà fermé. C'est tout! Je pense qu'il y a un malentendu car tu dis que tu n'es pas d'accord avec moi et ton exemple fait exactement ce que je dis (si ce n'est la ligne "exit-machin-truc()" que je supprimerai ). D'ailleurs si tu regardes le pattern "using" de C#, il fait exactement ce que je dis, en cas d'erreur tenter la fermeture et ignorer silencieusement l'éventuelle exception que cette dernière opération provoquerait afin qu'elle n'occulte pas l'erreur initiale, et je suis presque prêt à mettre ma main à couper que le "try" de java 7 fait grosso-modo la même chose. |
|
|
|
00
|
|
|
#13 | ||||
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Citation:
Citation:
En outre, pourquoi je dis ça ? C'est à cause du genre de code bien vache qui suit, et que j'ai déjà rencontré de manière plus complexe mais qui revenait au même dans certaines conditions : Code :
|
||||
|
00
|
|
|
#14 | |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 562 ![]() |
Citation:
Si tu dois remettre systématiquement en question le bon fonctionnement des interfaces, c'est la paranoïa car tu ne peux plus te fier à rien. |
|
|
|
10
|
|
|
#15 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Alors je propose d'en rester là sur le point du "close". J'ai ouvert un autre fil pour continuer la discussion : http://www.developpez.net/forums/d11...e/#post6251634
Après tout ce fil ci concerne l'article sur les fichier CSV et on est en train de diverger. Juste pour conclure, disons qu'il y a de la matière à discuter et que, dans tous les cas, le double "close" ne peut pas faire de mal. Au pire ça râle un peu, au mieux ça sauve des nuits. |
|
00
|
|
|
#16 |
|
Membre Expert
![]() Nicolas SaumandeArchitecte Décisionnel Inscription : février 2008 Messages : 750 ![]() |
Bonjour,
Une petite question naïve, dont vous ne me tiendrez pas rigueur (merci par avance). Quel serait l'intérêt de gérer la lecture de fichiers cvs via le code java que vous proposez, alors qu'il existe des outils ETL du genre Talend Open Studio qui le font très bien (et du coup faisable par les néophytes comme moi qui ne connaissent pas, ou peu, le language java)? Merci, Nicolas |
|
|
00
|
|
|
#17 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Très bonne question au contraire. J'en parle un peu dans l'article mais j'aurais pu insister un peu plus.
L'idée, déjà, c'est d'avoir une lib utilisable dans le programme qu'on est en train d'écrire. Ensuite, il existe des lib déjà toute faites, comme open-csv, qui font ce travail très bien. L'idée de l'article, ce n'est pas de savoir écrire une Nième lib sur le sujet, mais de comprendre les problèmes posés par la lecture CSV. D'ailleurs l'article fait (volontairement) l'impasse sur plusieurs points. Il y a un ensemble de compétences basiques à connaitre, et un ensemble de problématiques à prendre en compte. De manière générale, on peut être utilisateur d'un ETL sans jamais savoir ce qui se passe dedans. Par analogie, je n'ai aucune idée de ce qui peut se passer dans le moteur de ma voiture quand j'appuie sur la pédale d’accélération ou de frein. J'ai bien une vague idée mais alors vraiment vague. Mais je ne suis pas mécanicien. Par contre je suis développeur, donc à un moment ou un autre, il va falloir que je sache de quoi il retourne vraiment dans les programmes que j'utilise, surtout si je dois les recommander à un client. |
|
00
|
|
|
#18 |
|
Membre Expert
![]() Nicolas SaumandeArchitecte Décisionnel Inscription : février 2008 Messages : 750 ![]() |
Ok, je vois.
L'idée de l'article est de réfléchir à la problématique et non de proposer des solutions. Le fait que certains commentaires abordent les soucis rencontrés m'avait laissé un peu perplexe. De même que le fait que les limitations que vous citez sur les volumétries qui peuvent être traitées sont bien en dessous de ce que peuvent faire les ETL. En tout cas, merci d'avoir pris le temps de me répondre. Nicolas |
|
|
00
|
|
|
#19 |
![]() ![]() Thierry Leriche-DessirierInscription : octobre 2007 Messages : 2 131 ![]() |
Disons qu'en partant uniquement de cet article, ce n'est pas possible d'écrire un ETL ; il faut connaitre beaucoup d'autres choses. Par contre, je prend le cas de mes étudiants, à partir de cet article, ils vont apprendre plein de trucs. Et ils seront capables de faire des traitements rapides sur des fichiers pas trop complexes.
On a vu que, déjà, sur la fermeture des ressources, il y a plein de choses à savoir. |
|
00
|
Copyright © 2000-2013 - www.developpez.com