2010-10-11 58 views
5

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 a continuación:Analizando CSV en java

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

Todas las fechas muestran tras RunDate son los valores para el campo de fecha de ejecución y tengo que actualizar ese campo para esa compañía 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.

+0

no es una situación tan extraña como se podría pensar :) –

+0

Bibliotecas como [OpenCSV] (http://opencsv.sourceforge.net/) manejan todos los casos extraños para archivos CSV (líneas nuevas, delimitación, etc.). – Joshua

+0

Aunque no se presentan casos "extraños", el uso de una biblioteca (1) reducirá la posibilidad de errores en el análisis sintáctico; (2) proporcionar más características; (3) producir una solución extensible; y (4) integra fácilmente el análisis de futuros archivos CSV (si es necesario). –

Respuesta

4

divídalas por "," y analícelas y, Use List para agregar todos estos valores.

Como otro ha sugerido para la división y el análisis se puede utilizar opencsv

+0

-1 esto no manejará campos con comas en el campo, que es CSV perfectamente válido. La división en "," funciona en un caso simplista, pero solo ocasionalmente en uno realista. –

+0

@Dave DeLong puede elaborar su comentario –

+0

life.java Considere esta línea de csv: '" Hola ", mi, nombre, es, Dave'. Tiene 5 campos: 'Hello,' y 'my' y' name' y 'is' y' Dave'. Su sugerencia arrojaría 6: '" Hola', '" ',' mi', 'nombre',' es', y 'Dave' –

1

Se empieza por la lectura de 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?)

+0

Puede simplemente llamar a 'String.split (", ")'. –

+0

Gracias, intentaré recordarlo. Raramente utilizo una expresión regular. – camickr

1

Para obtener cada valor de uno en uno, utilice StringTokenizer. Constrúyalo 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).

+1

De la aplicación 'StringTokenizer': StringTokenizer es una clase heredada que se conserva por razones de compatibilidad, aunque se desaconseja su uso en el nuevo código. Se recomienda que cualquiera que busque esta funcionalidad use el método de división de String o el paquete java.util.regex en su lugar. – Qwerky

+0

: avergonzado: probablemente debería buscar la documentación antes de recomendar una respuesta.

+0

@Qwerky - Odio que hayan arrojado una clase perfectamente buena, pero estás en lo cierto. – KevinDTimm

2

use java.util.Scanner - puede llamar a 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.

2

Un archivo CSV es un archivo terminado \n que cada columna se puede separar mediante:

  • coma o
  • aquí \t

puedo sugerir que usted tiene un BufferedReader que lee la 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 .... desde allí, usted sabe qué hacer.

+0

La 'C' en' CSV' significa coma - google para 'TSV' para '' Valores separados por tabulaciones '' –

+0

@Stephen P, de hecho, pero ¿qué impide que alguien ponga pestañas en un archivo CSV? –

1

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

http://secretgeek.net/csv_trouble.asp

Básicamente, obtener una biblioteca establecida que lo haga por usted, porque el análisis sintáctico es csv engañosamente engañoso.

+0

Nada complicado ... es un archivo delimitado por comas o pestañas simples. –

+0

@The Elite: no leí el artículo publicado, ¿o sí? – KevinDTimm

+0

Lo hice ahora ... si Marcos pudiera hacerlo, también podría alguien ... * risa sarcástica * –

7

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.

¿Y si el nombre de la empresa es:
                Company, Inc.
o peor:
                Joe "bueno, rápido y barato" Comida


Según Wikipedia:         (http://en.wikipedia.org/wiki/Comma-separated_values)

Los campos con comas incrustadas deberá estar entre comillas dobles.

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

campos con comillas dobles incrustadas debe ser encerrado dentro de comillas dobles, y cada uno de los caracteres de doble cita incrustados debe ser representado por un par de comillas dobles.

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


Peor aún, los campos citados pueden haber encajado saltos de línea (saltos de línea; "\ n"):

Campos con saltos de línea interno debe estar encerrados dentro de comillas dobles.

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



Esto demuestra el problema con String, split ("") comas análisis sintáctico:

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, i


// 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 los siguientes:


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> 



Dónde 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 
+0

Bueno para proporcionar un código de demostración. –

+0

gracias! contento de hacerlo! –

0

Usted realmente debe tratar univocity-parsers como su analizador CSV viene con muchas características para manejar todo tipo de casos de esquina (comillas sin escape, los delimitadores de línea mixta, archivos codificados lista de materiales, etc.), que es también uno de los fastest CSV libraries alrededor.

ejemplo sencillo 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<String[]> 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. 

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