Cómo leer un archivo en una cadena Java: análisis bajo el capó

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cómo leer un archivo en una cadena Java: análisis de una pregunta popular de Stack Overflow

\n\n

Si alguna vez te has preguntado «How do I create a Java string from the contents of a file?» — no estás solo. Esta pregunta ha acumulado miles de visitas en Stack Overflow, y con razón. Una operación aparentemente trivial — leer un archivo de texto y colocar su contenido en una cadena — esconde numerosas trampas: desde fugas de memoria hasta problemas de codificación.

\n\n

En este artículo no solo daremos recetas ya preparadas. Analizaremos el funcionamiento interno de cada método: cómo funciona BufferedReader, por qué Files.readString() apareció solo en Java 11, y en qué se diferencia Scanner de InputStream. ¡Allá vamos!

\n\n

¿Por qué es más complejo de lo que parece?

\n\n

A primera vista, la tarea es trivial: hay un archivo, hay una cadena. Pero Java es un lenguaje con tipado estricto y gestión de memoria. Para leer un archivo, se necesita:

\n\n
    \n
  • Abrir un flujo de datos (InputStream, Reader)
  • \n
  • Bufferizar la lectura (para no acceder al disco por cada byte)
  • \n
  • Recolectar los bytes/caracteres en un búfer único
  • \n
  • Convertir a cadena teniendo en cuenta la codificación
  • \n
  • Cerrar los recursos (para evitar fugas de descriptores de archivo)
  • \n
\n\n

Cada uno de estos pasos es un punto potencial de fallo. Analicemos los enfoques más populares.

\n\n

Método 1: El clásico — BufferedReader (Java 1.1+)

\n\n

El método más antiguo y probado. Utiliza BufferedReader para la lectura línea por línea. Internamente, un búfer (por defecto de 8 KB) acumula datos, reduciendo la cantidad de llamadas al sistema read().

\n\n
public static String readFileBufferedReader(String filePath) throws IOException {\n    StringBuilder content = new StringBuilder();\n    try (BufferedReader reader = new BufferedReader(new FileReader(filePath, StandardCharsets.UTF_8))) {\n        String line;\n        while ((line = reader.readLine()) != null) {\n            content.append(line).append(System.lineSeparator());\n        }\n    }\n    return content.toString();\n}
\n\n

¿Cómo funciona internamente?

\n

FileReader abre el archivo y crea un FileInputStream. BufferedReader lo envuelve, añadiendo un búfer. Al llamar a readLine(), se lee un bloque de datos (por ejemplo, 8 KB) y la línea se ensambla desde el búfer. Si la línea es más larga que el búfer, este se relee. try-with-resources garantiza el cierre del flujo incluso si ocurre una excepción.

\n\n

Ventajas: Funciona en cualquier versión de Java, lectura línea por línea controlada.
\nDesventajas: Añade un separador de línea extra al final, no es eficiente para archivos enormes (cadena en memoria).

\n\n

Método 2: Scanner — cómodo pero lento (Java 5+)

\n\n

Muchos aman Scanner por su simplicidad. Puede dividir la entrada en tokens, pero para leer un archivo completo se usa así:

\n\n
public static String readFileScanner(String filePath) throws IOException {\n    try (Scanner scanner = new Scanner(new File(filePath), StandardCharsets.UTF_8.name())) {\n        scanner.useDelimiter("\\\\A"); // Inicio del archivo como delimitador\n        return scanner.hasNext() ? scanner.next() : "";\n    }\n}
\n\n

La magia de \\\\A: Es una expresión regular que denota el inicio de los datos de entrada. Al establecerlo como delimitador, obligamos a Scanner a leer todo el contenido de una sola vez. Internamente, Scanner utiliza Pattern para buscar el delimitador, lo que añade una sobrecarga por las expresiones regulares.

\n\n

Ventajas: Código muy conciso.
\nDesventajas: Más lento que BufferedReader debido al trabajo con expresiones regulares, no es adecuado para archivos binarios.

\n\n

Método 3: Files.readAllLines() — la comodidad de Java 8 (NIO)

\n\n

A partir de Java 8, el paquete java.nio.file ofreció una elegante

Blogs

Book Recommendations