Leer todo el texto de un archivo
Java 11 agregó el método readString () para leer archivos pequeños como String
terminadores de línea de preservación:
String content = Files.readString(path, StandardCharsets.US_ASCII);
Para las versiones entre Java 7 y 11, aquí hay un idioma compacto y robusto, envuelto en un método de utilidad:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Leer líneas de texto de un archivo
Java 7 agregó un método conveniente para leer un archivo como líneas de texto, representado como a List<String>
. Este enfoque es "con pérdida" porque los separadores de línea se eliminan del final de cada línea.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 agregó el Files.lines()
método para producir a Stream<String>
. Nuevamente, este método es con pérdida porque los separadores de línea se eliminan. Si IOException
se encuentra un mensaje al leer el archivo, se envuelve en un UncheckedIOException
, ya Stream
que no acepta lambdas que arrojan excepciones marcadas.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
Esto Stream
necesita una close()
llamada; esto está mal documentado en la API, y sospecho que muchas personas ni siquiera notan que Stream
tiene un close()
método. Asegúrese de usar un bloque ARM como se muestra.
Si está trabajando con una fuente que no sea un archivo, puede utilizar el lines()
método en su BufferedReader
lugar.
Utilización de la memoria
El primer método, que preserva los saltos de línea, puede requerir temporalmente memoria varias veces el tamaño del archivo, porque por un corto tiempo el contenido del archivo sin formato (una matriz de bytes) y los caracteres decodificados (cada uno de los cuales es de 16 bits, incluso si está codificado como 8 bits en el archivo) residen en la memoria a la vez. Es más seguro aplicarlo a archivos que sabe que son pequeños en relación con la memoria disponible.
El segundo método, la lectura de líneas, suele ser más eficiente en la memoria, ya que el búfer de bytes de entrada para la decodificación no necesita contener todo el archivo. Sin embargo, todavía no es adecuado para archivos que son muy grandes en relación con la memoria disponible.
Para leer archivos grandes, necesita un diseño diferente para su programa, uno que lea un fragmento de texto de una secuencia, lo procese y luego pase al siguiente, reutilizando el mismo bloque de memoria de tamaño fijo. Aquí, "grande" depende de las especificaciones de la computadora. Hoy en día, este umbral podría ser de muchos gigabytes de RAM. El tercer método, usar a Stream<String>
es una forma de hacerlo, si los "registros" de entrada son líneas individuales. (El uso del readLine()
método de BufferedReader
es el equivalente procesal a este enfoque).
Codificación de caracteres
Una cosa que falta en la muestra en la publicación original es la codificación de caracteres. Hay algunos casos especiales en los que el valor predeterminado de la plataforma es lo que desea, pero son raros y debería poder justificar su elección.
La StandardCharsets
clase define algunas constantes para las codificaciones requeridas de todos los tiempos de ejecución de Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
El valor predeterminado de la plataforma está disponible desde laCharset
propia clase :
String content = readFile("test.txt", Charset.defaultCharset());
Nota: Esta respuesta reemplaza en gran medida mi versión de Java 6. La utilidad de Java 7 simplifica de forma segura el código, y la respuesta anterior, que usaba un búfer de bytes mapeado, evitó que el archivo que se leía se eliminara hasta que el búfer mapeado se recogiera basura. Puede ver la versión anterior a través del enlace "editado" en esta respuesta.