write read poi mkyong example create crear java csv java.util.scanner

java - read - Leer CSV con escáner()



write csv java mkyong (7)

Bueno, hago mi codificación en NetBeans 8.1:

Primero: crea un nuevo proyecto, selecciona una aplicación Java y nombra tu proyecto.

Luego, modifique su código después de la clase pública para que se parezca a lo siguiente:

/** * @param args the command line arguments * @throws java.io.FileNotFoundException */ public static void main(String[] args) throws FileNotFoundException { try (Scanner scanner = new Scanner(new File("C://Users//YourName//Folder//file.csv"))) { scanner.useDelimiter(","); while(scanner.hasNext()){ System.out.print(scanner.next()+"|"); }} } }

Mi csv se lee en System.out, pero he notado que cualquier texto con un espacio se mueve a la siguiente línea (como un retorno / n)

Así es como comienza mi csv:

first,last,email,address 1, address 2 john,smith,[email protected],123 St. Street, Jane,Smith,[email protected],4455 Roger Cir,apt 2

Después de ejecutar mi aplicación, cualquier celda con un espacio (dirección 1), se lanza a la siguiente línea.

import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class main { public static void main(String[] args) { // -define .csv file in app String fileNameDefined = "uploadedcsv/employees.csv"; // -File class needed to turn stringName to actual file File file = new File(fileNameDefined); try{ // -read from filePooped with Scanner class Scanner inputStream = new Scanner(file); // hashNext() loops line-by-line while(inputStream.hasNext()){ //read single line, put in string String data = inputStream.next(); System.out.println(data + "***"); } // after loop, close scanner inputStream.close(); }catch (FileNotFoundException e){ e.printStackTrace(); } } }

Así que aquí está el resultado en la consola:

first,last,email,address 1,address 2 john,smith,[email protected],123 St. Street, Jane,Smith,[email protected],4455 Roger Cir,apt 2

¿Estoy usando el escáner incorrectamente?


Dividir nextLine () por este delimitador - (? = ([^ / "] /" [^ / "] /") [^ / "] $)") En una matriz.

Maneja tu problema


Estoy de acuerdo con Scheintod en que el uso de una biblioteca de CSV existente es una buena idea para tener conformidad con RFC-4180 desde el principio. Además de los mencionados OpenCSV y Oster Miller, hay una serie de otras bibliotecas de CSV disponibles. Si está interesado en el rendimiento, puede echar un vistazo a la uniVocity/csv-parsers-comparison . Muestra que

son consistentemente los más rápidos usando JDK 6, 7, 8 o 9. El estudio no encontró ningún problema de compatibilidad con RFC 4180 en ninguno de esos tres. Se ha descubierto que OpenCSV y Oster Miller son dos veces más lentos que aquellos.

No estoy asociado de ninguna manera con el (los) autor (es), pero con respecto al analizador uniVocity CSV, el estudio puede estar sesgado debido a que su autor es el mismo que el de ese analizador.

Para tener en cuenta, el autor de SimpleFlatMapper también ha publicado una comparación de rendimiento que compara solo esos tres.


Si debe usar Scanner, debe establecer su delimitador a través de su useDelimiter(...) . De lo contrario, utilizará por defecto todo el espacio en blanco como su delimitador. Mejor, como ya se dijo, use una biblioteca CSV ya que esto es lo que mejor hacen.

Por ejemplo, este delimitador se dividirá en comas con o sin espacios en blanco circundantes:

scanner.useDelimiter("//s*,//s*");

Consulte la API de java.util.Scanner para obtener más información al respecto.


Scanner.next() no lee una línea nueva sino que lee el siguiente token, delimitado por espacios en blanco (de forma predeterminada, si useDelimiter() no se usó para cambiar el patrón del delimitador). Para leer una línea use Scanner.nextLine() .

Una vez que lea una sola línea, puede usar String.split(",") para separar la línea en campos. Esto permite la identificación de líneas que no consisten en el número requerido de campos. Usando useDelimiter(","); ignoraría la estructura del archivo basada en líneas (cada línea consiste en una lista de campos separados por una coma). Por ejemplo:

while (inputStream.hasNextLine()) { String line = inputStream.nextLine(); String[] fields = line.split(","); if (fields.length >= 4) // At least one address specified. { for (String field: fields) System.out.print(field + "|"); System.out.println(); } else { System.err.println("Invalid record: " + line); } }

Como ya se mencionó, se recomienda usar una biblioteca CSV. Por un lado, esta (y la useDelimiter(",") ) no manejará correctamente los identificadores entre comillas que contienen los caracteres.


¡Por favor, deja de escribir analizadores de CSV defectuosos!

He visto cientos de analizadores de CSV y los llamados tutoriales para ellos en línea.

¡Casi todos se equivocan!

Esto no sería tan malo ya que no me afecta, pero las personas que intentan escribir lectores CSV y se equivocan tienden a escribir también escritores de CSV. Y que también se equivoquen. Y estos para los que tengo que escribir analizadores.

Tenga en cuenta que CSV (en orden de aumentar no tan obvio):

  1. puede tener citas de caracteres alrededor de los valores
  2. puede tener otros caracteres de cotización que "
  3. incluso puede tener otros caracteres de cotización que "y ''
  4. no puede citar caracteres en absoluto
  5. incluso puede haber comillas de caracteres en algunos valores y ninguno en otros
  6. puede tener otros separadores que, y;
  7. puede tener espacios en blanco entre separadores y valores (cotizados)
  8. puede tener otros conjuntos de caracteres que ascii
  9. debería tener el mismo número de valores en cada fila, pero no siempre
  10. puede contener campos vacíos, ya sean citados: "foo","","bar" o no: "foo",,"bar"
  11. puede contener nuevas líneas en los valores
  12. no puede contener nuevas líneas en los valores si no están delimitadas
  13. no puede contener nuevas líneas entre los valores
  14. puede tener el carácter delimitador dentro del valor si se escapó correctamente
  15. no usa barra invertida para escapar de los delimitadores, pero ...
  16. utiliza el personaje que cita para escapar, por ejemplo, Frodo''s Ring será ''Frodo''''s Ring''
  17. puede tener el carácter de comillas al principio o al final del valor, o incluso como único carácter ( "foo""", """bar", """" )
  18. incluso puede tener el carácter entrecomillado dentro del valor no citado; este no se escapó

Si crees que esto es obvio no es un problema, entonces piénsalo de nuevo. He visto todos y cada uno de estos elementos implementados incorrectamente. Incluso en los principales paquetes de software. (por ejemplo, Office-Suites, CRM Systems)

Hay buenos y correctos lectores y escritores de CSV listos para usar:

Si insiste en escribir el suyo, al menos lea el (muy corto) RFC para CSV .


scanner.useDelimiter(",");

Esto debería funcionar.

import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class TestScanner { public static void main(String[] args) throws FileNotFoundException { Scanner scanner = new Scanner(new File("/Users/pankaj/abc.csv")); scanner.useDelimiter(","); while(scanner.hasNext()){ System.out.print(scanner.next()+"|"); } scanner.close(); } }

Para el archivo CSV:

a,b,c d,e 1,2,3 4,5 X,Y,Z A,B

La salida es:

a|b|c d|e 1|2|3 4|5 X|Y|Z A|B|