¿Cómo creo una cadena Java a partir del contenido de un archivo?

Resuelto OscarRyz asked hace 15 años • 35 respuestas

He estado usando el siguiente modismo desde hace algún tiempo. Y parece ser el más extendido, al menos en los sitios que he visitado.

¿Existe una forma mejor/diferente de leer un archivo en una cadena en Java?

private String readFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader (file));
    String line = null;
    StringBuilder stringBuilder = new StringBuilder();
    String ls = System.getProperty("line.separator");

    try {
        while((line = reader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append(ls);
        }

        return stringBuilder.toString();
    } finally {
        reader.close();
    }
}
OscarRyz avatar Nov 29 '08 01:11 OscarRyz
Aceptado

Leer todo el texto de un archivo

Java 11 agregó el método readString() para leer archivos pequeños como un archivo String, preservando los terminadores de línea:

String content = Files.readString(path, encoding);

Para las versiones entre Java 7 y 11, aquí hay un lenguaje 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, representadas como un archivo List<String>. Este enfoque tiene "pérdidas" 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 un archivo Stream<String>. Nuevamente, este método genera pérdidas porque se eliminan los separadores de línea. Si IOExceptionse encuentra an mientras se lee el archivo, se envuelve en an UncheckedIOException, ya que Streamno acepta lambdas que arrojan excepciones marcadas.

try (Stream<String> lines = Files.lines(path, encoding)) {
  lines.forEach(System.out::println);
}

Esto Streamnecesita una close()llamada; Esto está mal documentado en la API y sospecho que muchas personas ni siquiera se dan cuenta de Streamque existe un close()método. Asegúrese de utilizar un bloque ARM como se muestra.

Si está trabajando con una fuente que no sea un archivo, puede utilizar el lines()método en BufferedReadersu lugar.

Utilización de la memoria

Si su archivo es lo suficientemente pequeño en relación con la memoria disponible, leer el archivo completo de una vez podría funcionar bien. Sin embargo, si su archivo es demasiado grande, leer una línea a la vez, procesarla y luego descartarla antes de pasar a la siguiente podría ser un mejor enfoque. El procesamiento de secuencias de esta manera puede eliminar el tamaño total del archivo como factor en los requisitos de memoria.

Codificación de caracteres

Una cosa que falta en el ejemplo de la publicación original es la codificación de caracteres. Esta codificación generalmente no se puede determinar a partir del archivo en sí y requiere metadatos, como un encabezado HTTP, para transmitir esta información importante.

La StandardCharsetsclase 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 en laCharset propia clase :

String content = readFile("test.txt", Charset.defaultCharset());

Hay algunos casos especiales en los que la plataforma predeterminada es la que usted desea, pero son poco frecuentes. Debería poder justificar su elección, porque la plataforma predeterminada no es portátil. Un ejemplo en el que podría ser correcto es al leer la entrada estándar o escribir la salida estándar.


Nota: esta respuesta reemplaza en gran medida mi versión de Java 6. La utilidad de Java 7 simplifica el código de forma segura, y la respuesta anterior, que utilizaba un búfer de bytes asignado, impedía que el archivo leído se eliminara hasta que el búfer asignado fuera recolectado como basura. Puede ver la versión anterior a través del enlace "editado" en esta respuesta.

erickson avatar Nov 28 '2008 18:11 erickson

Si está dispuesto a utilizar una biblioteca externa, consulte Apache Commons IO (JAR de 200 KB). Contiene un org.apache.commons.io.FileUtils.readFileToString()método que le permite leer un archivo completo Fileen una Stringsola línea de código.

Ejemplo:

import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;

public String readFile() throws IOException {
    File file = new File("data.txt");
    return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}
DaWilli avatar Nov 28 '2008 18:11 DaWilli

Una solución muy sencilla basada en Scanner:

Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

O, si desea configurar el juego de caracteres:

Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

O bien, con un bloque de prueba con recursosscanner.close() , que le solicitará :

try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
    String text = scanner.useDelimiter("\\A").next();
}

Recuerde que el Scannerconstructor puede lanzar un IOException. Y no olvides importar java.ioy java.util.

Fuente: blog de Pat Niemeyer

Pablo Grisafi avatar Sep 16 '2011 20:09 Pablo Grisafi