2011-09-14 10 views
49

Mi programa debe leer archivos de texto - línea por línea. Archivos en UTF-8. No estoy seguro de que los archivos sean correctos; pueden contener caracteres no imprimibles. ¿Es posible verificarlo sin pasar al nivel de bytes? Gracias.Comprobar línea para caracteres no imprimibles al leer el archivo de texto

+0

¿Desea marcar una sola línea, o el archivo completo? –

+0

¿Está garantizado que las alimentaciones de línea son correctas? – Tarnschaf

+0

marca una sola línea. Sí, las alimentaciones de línea son correctas. – user710818

Respuesta

15

Si desea comprobar una cadena tiene caracteres no imprimibles se puede utilizar una expresión regular

[^\p{Print}] 
+0

Esto, sin embargo, incluye los espacios en blanco y los caracteres de tabulación en su conjunto de caracteres que no se imprimen mientras que influyen en el lugar de las palabras en la página. –

49

Si bien no es difícil hacer esto manualmente usando BufferedReader y InputStreamReader, que haría uso de Guava:

List<String> lines = Files.readLines(file, Charsets.UTF_8); 

A continuación, puede hacer lo que quiera con esas líneas.

EDITAR: Tenga en cuenta que esto leerá todo el archivo en la memoria de una vez. En la mayoría de los casos, eso está realmente bien, y ciertamente es más simple que leyéndola línea por línea, procesando cada línea a medida que la lee. Si se trata de un archivo enorme, es posible que deba hacerlo de esa manera según T.J. La respuesta de Crowder.

+4

Guava alse proponen un método con devolución de llamada Files.readLines (Archivo, Charset charset, LineProcessor callback) – Vlagorce

+0

Si el propósito es procesar línea por línea, usar BufferedRead es tan simple. También es excesivo agregar otra dependencia de biblioteca solo para la lectura de líneas, mientras que la biblioteca principal de Java ya lo admite. – user172818

+5

@ user172818: No, no es tan simple ... al menos no si no está utilizando Java 7 con su declaración try-with-resources. Además, estaría * asombrado * en cualquier programa Java no trivial que no pudiera beneficiarse de Guava en * lugares * múltiples. Es una gran biblioteca, y no estaría sin ella. –

121

Abrir el archivo con un FileInputStream, a continuación, utilizar una InputStreamReader con el UTF-8 Charset para leer caracteres de la corriente, y utilizar un BufferedReader para leer las líneas, por ejemplo a través de BufferedReader#readLine, que le dará una cadena. Una vez que tenga la cadena, puede verificar si hay caracteres que no son lo que considera imprimibles.

E.g. (Sin comprobación de errores), utilizando try-with-resources (que está en vagamente moderna versión de Java):

String line; 
try (
    InputStream fis = new FileInputStream("the_file_name"); 
    InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8")); 
    BufferedReader br = new BufferedReader(isr); 
) { 
    while ((line = br.readLine()) != null) { 
     // Deal with the line 
    } 
} 
+1

O, para un paso menos, abra el archivo con un FileReader y use un BufferedReader para leer las líneas. –

+1

@stviper: Y ahora es 2015, lo he actualizado para usar try-with-resources, mucho más limpio. :-) –

+1

@ abhisheknaik96: Gracias por su edición, pero solo el bit 'isr' era correcto; el '()' se ** supone ** que es '()', no '{}', y el último punto y coma no es obligatorio (pero está permitido, así que lo dejé, más acorde con el líneas arriba). –

1

Si cada caracter en el archivo está codificado adecuadamente en UTF-8, no tendrá ningún problema para leerlo usando un lector con la codificación UTF-8. Depende de usted comprobar cada carácter del archivo y ver si lo considera imprimible o no.

42

acabo de enterar que con el Java NIO (java.nio.file.*) se puede escribir fácilmente:

List<String> lines=Files.readAllLines(Paths.get("/tmp/test.csv"), Charset.forName("UTF-8")); 
for(String line:lines){ 
    System.out.println(line); 
} 

en lugar de tratar con FileInputStream sy BufferedReader s ...

+0

Solo quiero agregar, java.nio.file. * Está disponible desde JDK 7 –

+3

Puede valer la pena mencionar el documento de [Files.readAllLines] (http://docs.oracle.com/javase/7/docs/api) /java/nio/file/Files.html): este método está pensado para casos simples en los que es conveniente leer todas las líneas en una sola operación. No está destinado a la lectura en archivos de gran tamaño. –

11

¿Qué le parece a continuación:

FileReader fileReader = new FileReader(new File("test.txt")); 

BufferedReader br = new BufferedReader(fileReader); 

String line = null; 
// if no more lines the readLine() returns null 
while ((line = br.readLine()) != null) { 
     // reading lines until the end of the file 

} 

Fuente: http://devmain.blogspot.co.uk/2013/10/java-quick-way-to-read-or-write-to-file.html

+0

No, elimine esto, está utilizando la codificación predeterminada, e ingrese a un mundo de dolor. –

3

La respuesta por @TJCrowder es Java 6 - 7 en java la respuesta válida es el uno por @McIntosh - aunque su uso del juego de caracteres para el nombre de UTF -8 se desanima:

List<String> lines = Files.readAllLines(Paths.get("/tmp/test.csv"), 
    StandardCharsets.UTF_8); 
for(String line: lines){ /* DO */ } 

recuerda mucho a la forma de guayaba publicado por Skeet anterior - y por supuesto se aplican mismas advertencias. Es decir, para archivos grandes (Java 7):

BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8); 
for (String line = reader.readLine(); line != null; line = reader.readLine()) {} 
5

Puedo encontrar las siguientes formas de hacerlo.

private static final String fileName = "C:/Input.txt"; 

public static void main(String[] args) throws IOException { 
    Stream<String> lines = Files.lines(Paths.get(fileName)); 
    lines.toArray(String[]::new); 

    List<String> readAllLines = Files.readAllLines(Paths.get(fileName)); 
    readAllLines.forEach(s -> System.out.println(s)); 

    File file = new File(fileName); 
    Scanner scanner = new Scanner(file); 
    while (scanner.hasNext()) { 
     System.out.println(scanner.next()); 
    } 
Cuestiones relacionadas