La clase Reader en Java es una herramienta fundamental para leer datos en modo carácter desde distintas fuentes, siendo FileReader una de sus implementaciones más comunes para trabajar con archivos de texto. Cuando creamos un FileReader, le indicamos el archivo que queremos leer, y opcionalmente el charset que deseamos utilizar para interpretar los caracteres. Esto nos permite acceder a métodos básicos como close, mark, read o reset, que controlan la lectura y el manejo del flujo de datos.
El método read es especialmente interesante porque nos permite leer carácter a carácter, aunque devuelve un valor entero para evitar problemas con la representación de caracteres. Por eso, es necesario hacer un casteo a carácter cuando queremos trabajar con el dato leído. También podemos leer en bloques utilizando buffers, que son arrays de caracteres, para procesar varios caracteres a la vez. Sin embargo, esta forma de leer puede resultar poco práctica y algo compleja, especialmente si no estamos familiarizados con clases más avanzadas como CharBuffer.
Para facilitar la lectura secuencial de cadenas de caracteres, especialmente cuando queremos procesar archivos línea a línea, es mucho más común y eficiente utilizar la clase BufferedReader. Esta clase actúa como una capa bufferizada sobre un Reader, lo que mejora el rendimiento y nos proporciona métodos muy útiles para trabajar con texto. Por ejemplo, BufferedReader nos permite leer líneas completas con el método readLine, que internamente llama a read repetidamente hasta encontrar un delimitador de fin de línea o el final del archivo.
Al usar BufferedReader, normalmente lo instanciamos envolviendo un FileReader, de modo que todas las llamadas a métodos de BufferedReader se traducen en llamadas al Reader original, pero con la ventaja de contar con funcionalidades adicionales. Además de readLine, BufferedReader ofrece el método lines, que devuelve un stream de líneas, facilitando la lectura en estilos más modernos y funcionales.
Una forma práctica y común de leer un archivo de texto línea a línea con BufferedReader es utilizar un bucle que vaya leyendo cada línea hasta que el método readLine devuelva null, lo que indica que hemos llegado al final del archivo. Para ello, podemos declarar una variable de tipo String que almacene la línea leída en cada iteración y, mientras esta variable no sea null, procesar o imprimir la línea.
Un ejemplo sencillo de este patrón sería:
try (BufferedReader br = new BufferedReader(new FileReader("hola.txt"))) {
String linea;
while ((linea = br.readLine()) != null) {
System.out.println(linea);
}
} catch (IOException e) {
e.printStackTrace();
}
Este código abre el archivo hola.txt para lectura, y dentro de un bloque try-with-resources que asegura el cierre automático del lector, lee línea a línea hasta agotar el contenido, imprimiendo cada línea en la consola.
Aunque existen otras clases y métodos para interactuar con un Reader, como escáneres o parsers más especializados, el uso de BufferedReader para leer archivos de texto línea a línea es una de las formas más simples y eficientes para manejar datos en Java. Esta técnica es especialmente útil cuando queremos procesar archivos de texto de manera secuencial y sencilla, sin complicarnos con la lectura carácter a carácter o con buffers manuales.