Je veux écrire un programme pour une école Java projet pour analyser certains CSV que je ne connais pas. Je connais le type de données de chaque colonne - bien que je ne connaisse pas le délimiteur.
Le problème que je ne sais même pas comment résoudre, c'est d'analyser les colonnes Date ou même DateTime. Ils peuvent être dans l'un des nombreux formats.
J'ai trouvé de nombreuses bibliothèques mais je n'ai aucune idée de ce qui convient le mieux à mes besoins: http://opencsv.sourceforge.net/http://www.csvreader.com/Java_csv.phphttp://supercsv.sourceforge.net/http://flatpack.sourceforge.net/
Le problème est que je suis un débutant Java débutant. Je crains qu'aucune de ces bibliothèques ne puisse faire ce dont j'ai besoin ou que je ne puisse pas les convaincre de le faire.
Je parie qu'il y a beaucoup de gens ici qui ont un exemple de code qui pourrait me permettre de démarrer en un rien de temps pour ce dont j'ai besoin:
Ce serait bien d'obtenir autant d'échantillons de code que possible par e-mail.
Merci beaucoup! COMME
Il y a un sérieux problème avec l'utilisation
String[] strArr=line.split(",");
afin d'analyser les fichiers CSV, et c'est parce qu'il peut y avoir des virgules dans les valeurs de données, et dans ce cas, vous devez les citer, et ignorer les virgules entre guillemets.
Il existe un moyen très très simple d'analyser ceci:
/**
* returns a row of values as a list
* returns null if you are past the end of the input stream
*/
public static List<String> parseLine(Reader r) throws Exception {
int ch = r.read();
while (ch == '\r') {
//ignore linefeed chars wherever, particularly just before end of file
ch = r.read();
}
if (ch<0) {
return null;
}
Vector<String> store = new Vector<String>();
StringBuffer curVal = new StringBuffer();
boolean inquotes = false;
boolean started = false;
while (ch>=0) {
if (inquotes) {
started=true;
if (ch == '\"') {
inquotes = false;
}
else {
curVal.append((char)ch);
}
}
else {
if (ch == '\"') {
inquotes = true;
if (started) {
// if this is the second quote in a value, add a quote
// this is for the double quote in the middle of a value
curVal.append('\"');
}
}
else if (ch == ',') {
store.add(curVal.toString());
curVal = new StringBuffer();
started = false;
}
else if (ch == '\r') {
//ignore LF characters
}
else if (ch == '\n') {
//end of a line, break out
break;
}
else {
curVal.append((char)ch);
}
}
ch = r.read();
}
store.add(curVal.toString());
return store;
}
Cette approche présente de nombreux avantages. Notez que chaque caractère est touché EXACTEMENT une fois. Il n'y a pas de lecture en avant, de repoussage dans le tampon, etc. Pas de recherche en avant jusqu'à la fin de la ligne, puis de copier la ligne avant l'analyse. Cet analyseur fonctionne uniquement à partir du flux et crée chaque valeur de chaîne une fois. Cela fonctionne sur les lignes d'en-tête et les lignes de données, il vous suffit de traiter la liste renvoyée appropriée à cela. Vous lui donnez un lecteur, donc le flux sous-jacent a été converti en caractères en utilisant l'encodage que vous choisissez. Le flux peut provenir de n'importe quelle source: un fichier, une publication HTTP, un get HTTP et vous analysez le flux directement. Il s'agit d'une méthode statique, il n'y a donc aucun objet à créer et à configurer, et lorsque cela revient, il n'y a plus de mémoire.
Vous pouvez trouver une discussion complète de ce code, et pourquoi cette approche est préférée dans mon article de blog sur le sujet: La seule classe dont vous avez besoin pour les fichiers CSV .
Vous avez également la bibliothèque Apache Commons CSV , peut-être qu'elle fait ce dont vous avez besoin. Voir le guide . Mise à jour vers la version 1.1 en 2014-11.
De plus, pour l'édition infaillible, je pense que vous devrez le coder vous-même ... à travers SimpleDateFormat
vous pouvez choisir vos formats et spécifier différents types, si le Date
ne ressemble à aucun de vos types prédéfinis, ce n'est pas une date.
Mon approche serait pas de commencer par écrire votre propre API. La vie est trop courte et il y a des problèmes plus urgents à résoudre. Dans cette situation, je typiquement:
Commencez avec quelque chose que quelqu'un a déjà écrit. Les chances sont que ça fera ce que vous voulez. Vous pouvez toujours écrire le vôtre plus tard, si nécessaire. OpenCSV est un aussi bon point de départ que n'importe quel autre.
Vous voudrez peut-être jeter un œil à cette spécification pour CSV. Gardez à l'esprit qu'il n'existe aucune spécification officielle reconnue.
Si vous n'avez pas maintenant le délimiteur, il ne sera pas possible de le faire, vous devez donc le découvrir d'une manière ou d'une autre. Si vous pouvez effectuer une inspection manuelle du fichier, vous devriez rapidement pouvoir voir de quoi il s'agit et coder en dur dans votre programme. Si le délimiteur peut varier, votre seul espoir est de pouvoir le déduire de la mise en forme des données connues. Lorsque Excel importe des fichiers CSV, il permet à l'utilisateur de choisir le délimiteur et c'est une solution que vous pouvez également utiliser.
j'ai dû utiliser un analyseur csv il y a environ 5 ans. semble qu'il existe au moins deux normes csv: http://en.wikipedia.org/wiki/Comma-separated_values et ce que Microsoft fait dans Excel.
j'ai trouvé ce libaray qui mange à la fois: http://ostermiller.org/utils/CSV.html , mais afaik, il n'a aucun moyen de déduire de quel type de données étaient les colonnes.
Je suis d'accord avec @Brian Clapper. J'ai utilisé SuperCSV comme analyseur bien que j'aie eu des résultats mitigés. J'apprécie la polyvalence de celui-ci, mais il y a des situations dans mes propres fichiers csv pour lesquelles je n'ai pas pu réconcilier "encore". J'ai confiance en ce produit et je le recommanderais dans l'ensemble - il me manque quelque chose de simple, sans aucun doute, que je fais dans ma propre mise en œuvre.
SuperCSV peut analyser les colonnes dans différents formats, effectuer des modifications sur les colonnes, etc. Cela vaut la peine d'y jeter un œil. Il contient également des exemples et est facile à suivre.
La seule/unique limitation que j'ai est d'attraper une colonne `` vide '' et de l'analyser en entier ou peut-être en blanc, etc. Donc, je me blâme d'abord, pour l'instant. :-)
Quoi qu'il en soit, jetez un œil à SuperCSV. http://supercsv.sourceforge.net/
Je vous recommande de commencer par séparer votre tâche en ses composants.
Une fois que vous avez fait cela, il devrait être assez simple d'utiliser l'une des bibliothèques auxquelles vous vous connectez (qui gérera certainement la tâche # 1). Ensuite, parcourez les valeurs renvoyées et convertissez/convertissez chaque valeur de chaîne en la valeur souhaitée.
Si la question est de savoir comment convertir des chaînes en différents objets, cela dépendra du format avec lequel vous commencez et du format avec lequel vous souhaitez vous retrouver.
DateFormat.parse (), par exemple, analysera les dates des chaînes. Voir SimpleDateFormat pour construire rapidement un DateFormat pour une certaine représentation de chaîne. Integer.parseInt () supprimera les entiers des chaînes.
Devise, vous devrez décider comment vous voulez la capturer. Si vous souhaitez simplement capturer comme un flottant, alors Float.parseFloat () fera l'affaire (utilisez simplement String.replace () pour supprimer tous les $ et virgules avant de l'analyser). Ou vous pouvez analyser dans un BigDecimal (afin que vous n'ayez pas de problèmes d'arrondi). Il peut y avoir une meilleure classe pour le traitement des devises (je ne fais pas beaucoup de cela, donc je ne connais pas ce domaine du JDK).
Fondamentalement, vous devrez lire le fichier ligne par ligne.
Ensuite, vous devrez diviser chaque ligne par le délimiteur, par exemple une virgule (CSV signifie valeurs séparées par des virgules), avec
String[] strArr=line.split(",");
Cela le transformera en un tableau de chaînes que vous pourrez ensuite manipuler, par exemple avec
String name=strArr[0];
int yearOfBirth = Integer.valueOf(strArr[1]);
int monthOfBirth = Integer.valueOf(strArr[2]);
int dayOfBirth = Integer.valueOf(strArr[3]);
GregorianCalendar dob=new GregorianCalendar(yearOfBirth, monthOfBirth, dayOfBirth);
Student student=new Student(name, dob); //lets pretend you are creating instances of Student
Vous devrez le faire pour chaque ligne, donc encapsulez ce code dans une boucle while. (Si vous ne connaissez pas le délimiteur, ouvrez simplement le fichier dans un éditeur de texte.)
Écrire votre propre analyseur est amusant, mais vous devriez probablement jeter un œil à Open CSV . Il offre de nombreuses façons d'accéder au CSV et permet également de générer du CSV. Et il gère correctement les échappements. Comme mentionné dans un autre article, il existe également une bibliothèque d'analyse CSV dans Apache Commons, mais celle-ci n'est pas encore publiée.
Vous devrez au moins connaître le délimiteur de colonne.