Analizando CSV en java

Tengo esta extraña situación en la que tengo que leer horizontalmente. Así que estoy obteniendo un archivo csv que tiene datos en formato horizontal. Como abajo:

CompanyName,RunDate,10/27/2010,11/12/2010,11/27/2010,12/13/2010,12/27/2010.... 

Todas las fechas que se muestran después de RunDate son valores para el campo de fecha de ejecución y tengo que actualizar ese campo para esa empresa en mi sistema. Los valores de fecha no son el número de corrección, pueden ser de un solo valor hasta 10 en n número. Entonces necesito leer todos esos valores y actualizarlos en el sistema. Estoy escribiendo esto en Java.

Cadena, división (“,”) no es probable que funcione.
Dividirá los campos que tienen comas incrustadas (“Foo, Inc.”) aunque sean un solo campo en la línea CSV.

¿Qué pasa si el nombre de la empresa es:
Company, Inc.
o peor:
La comida “buena, rápida y barata” de Joe

De acuerdo con Wikipedia: ( http://en.wikipedia.org/wiki/Comma-separated_values )

Los campos con comas incrustadas deben estar entre caracteres de comillas dobles.

  1997,Ford,E350,"Super, luxurious truck" 

Los campos con caracteres de comillas dobles incrustados deben estar entre caracteres de comillas dobles, y cada uno de los caracteres de comillas dobles debe representarse mediante un par de caracteres de comillas dobles.

  1997,Ford,E350,"Super ""luxurious"" truck" 

Peor aún, los campos entre comillas pueden tener saltos de línea integrados (líneas nuevas; “\ n”):

Los campos con saltos de línea incrustados deben estar entre caracteres de comillas dobles.

  1997,Ford,E350,"Go get one now they are going fast" 

Esto demuestra el problema con String, split (“,”) comas de análisis:

La línea CSV es:

a, b, c, “Company, Inc.”, d, e, “Joe’s” “Bueno, rápido y barato” “Comida”, f, 11/10 / 2010,1 / 1/2011, g, h, yo

 // Test String.split(",") against CSV with // embedded commas and embedded double-quotes in // quoted text strings: // // Company names are: // Company, Inc. // Joe's "Good, Fast, and Cheap" Food // // Which should be formatted in a CSV file as: // "Company, Inc." // "Joe's ""Good, Fast, and Cheap"" Food" // // public class TestSplit { public static void TestSplit(String s, String splitchar) { String[] split_s = s.split(splitchar); for (String seg : split_s) { System.out.println(seg); } } public static void main(String[] args) { String csvLine = "a,b,c,\"Company, Inc.\", d," + " e,\"Joe's \"\"Good, Fast," + " and Cheap\"\" Food\", f," + " 10/11/2010,1/1/2011, h, i"; System.out.println("CSV line is:\n" + csvLine + "\n\n"); TestSplit(csvLine, ","); } } 

Produce lo siguiente:

 D:\projects\TestSplit>javac TestSplit.java D:\projects\TestSplit>java TestSplit CSV line is: a,b,c,"Company, Inc.", d, e,"Joe's ""Good, Fast, and Cheap"" Food", f, 10/11/2010,1/1/2011, g, h, i a b c "Company Inc." d e "Joe's ""Good Fast and Cheap"" Food" f 10/11/2010 1/1/2011 g h i D:\projects\TestSplit> 

Donde esa línea CSV debe ser analizada como:

 a b c "Company, Inc." d e "Joe's ""Good, Fast, and Cheap"" Food" f 10/11/2010 1/1/2011 g h i 

Como otros han sugerido para dividir y analizar, puede usar opencsv

Para datos simples, divídalos por “,” y analícelos y, Use List para agregar todos estos valores.

Un archivo CSV es un archivo terminado \n nque cada columna puede separarse ya sea por:

  • Coma o
  • Pestañas \t

Sugiero que tenga un BufferedReader que lea el archivo CSV y use el método readLine() para leer la fila.

De cada fila, use String.split(arg) donde arg será su coma o pestaña \t para tener una matriz de columnas … a partir de ahí, ya sabe qué hacer.

use java.util.Scanner – puede llamar useDelimiter () para hacer que la coma sea su delimitador, y leer nuevos tokens con next (). El escáner se puede crear directamente desde su archivo o una cadena de lectura del archivo.

Con mucho, la página más útil sobre el tema del análisis de CSV que he encontrado es la siguiente:

http://secretgeek.net/csv_trouble.asp

Básicamente, obtenga una biblioteca establecida para que lo haga por usted, porque el análisis de csv es engañosamente engañoso.

Deberías probar univocity-parser ya que su analizador CSV viene con muchas características para manejar todo tipo de casos de esquina (comillas no guardadas, delimitadores de líneas mixtas, archivos codificados BOM, etc.), que también es una de las bibliotecas CSV más rápidas .

Ejemplo simple para analizar un archivo:

 CsvParserSettings settings = new CsvParserSettings(); //heaps of options here, check the docs CsvParser parser = new CsvParser(settings); //loads everything into memory, simple but can be slow. List allRows = parser.parseAll(new File("/path/to/your.csv")); //parse iterating over each row for(String[] row : parser.iterate(new File("/path/to/your.csv"))){ //process row here } //and many other possibilities: Java bean processing, column selection, format detection, etc. 

Divulgación: soy el autor de esta biblioteca. Es de código abierto y gratuito (licencia de Apache V2.0).

Empiezas leyendo toda la línea en una cadena. Luego usa la función String.split (…) para obtener todos los tokens en la línea donde el delimitador que usa es “,”. (¿o es “\” cuando usa una expresión regular?)

Para obtener cada valor uno a la vez, use un StringTokenizer . StringTokenizer(str, ",") con StringTokenizer(str, ",") . (No recomendado)

Utilice el método split() de la clase de cadena, que carga todos los tokens en una matriz.

Utilice la clase DateFormat para analizar cada fecha, específicamente DateFormat.parse(String) .