Read file line by line with Java 5


import java.io.FileInputStream;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Scanner;

public class ReadFileByLines {
 
  public static void main(String... args) throws Exception {
   
    FileChannel fc = new FileInputStream("/usr/foo.txt").getChannel();
   
    MappedByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
    Charset charset = Charset.forName("ISO-8859-1");
    CharsetDecoder decoder = charset.newDecoder();
    CharBuffer charBuffer = decoder.decode(byteBuffer);
   
    // Read file line by line
    Scanner sc = new Scanner(charBuffer).useDelimiter("\n");
   
    while (sc.hasNext()) {
        String line = sc.next();     
        System.out.println(line);
    }
    fc.close();

  }

}

2 comentarios en “Read file line by line with Java 5

  1. Parece más farragoso que la forma tradicional con InputStreamReader y BufferedStreamReader. ¿Tiene ventajas? Lo cierto es que tengo mucho interés…

    Por otro lado, el separador de línea ‘\n’ no debería asumirse (¿y si el fichero se creó en Mac?), eso te lo abstrae el método BufferedReader.readLine().

    Y sobre el character encoding, hace poco precisamente me ha surgido el problema de autodetectarlo. http://jchardet.sourceforge.net/ es un porting a Java de la librería que usan en Mozilla para detectar encodings y páginas de códigos, aunque a mi me dio algún problema. Terminé por hacer un pequeño detector que discrinaba entre windows-1252, iso-8859-1 y UTF-8 Latin 1… Obviamente sobrecargas el asunto pero me parece muy interesante para evitar sorpresas…

  2. [English]
    Line separator detection equivalent to BufferedReader.readLine():
    Scanner.useDelimiter(System.getProperty(“line.separator”))

    Encoding issues: http://mindprod.com/jgloss/encoding.html#IDENTIFICATION

    [Spanish]
    Lo cierto es que cambié el código tradicional (InputStream + BufferedStream) en un proceso pesado porque tardaba más de lo esperado en procesar los ficheros. Tras el cambio la mejora en tiempo fue espectacular.

    Sin embargo, aislando el código observo que la solución NIO es más lenta que la IO. ¿Quizá porque la solución IO es dependiente de la cantidad de memoria disponible?

    En cuanto al separador de línea, el método BufferedReader.readLine() es equivalente a utilizar en el código de arriba Scanner.useDelimiter(System.getProperty(“line.separator”)). Pero ambos tienen una pega: utilizan el separador de línea del sistema en el que estás ejecutando el código. Esto es, si por ejemplo lees ficheros generados en Linux desde una máquina Windows, buscará un \n\r.

    En cuanto al encoding, te recomiendo que consultes http://mindprod.com/jgloss/encoding.html#IDENTIFICATION.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s