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

1636

He estado usando el siguiente modismo durante 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();
    }
}
10
  • 7
    ¿Alguien puede explicarme de una manera muy sencilla qué pasa con el NIO? Cada vez que leo sobre él, me pierdo en la enésima mención del canal :(OscarRyz 28 de nov. De 2008 a las 18:33
  • 7
    recuerde que no está garantizado que el separador de línea en el archivo no sea necesario al igual que el separador de línea del sistema. Henrik Paul 28 de nov. De 2008 a las 18:35
  • 6
    El código anterior tiene un error de agregar un carácter de línea nueva adicional en la última línea. Debería ser algo como seguir if (línea = reader.readLine ())! = Null) {stringBuilder.append (line); } while (línea = reader.readLine ())! = null) {stringBuilder.append (ls); stringBuilder.append (línea); }Deep 12/08/11 a las 10:29
  • 29
    Java 7 presenta byte[] Files.readAllBytes(file);Para aquellos que sugieren la solución de escáner de 'una línea': ¿No es necesario cerrarla? Val 17/01/12 a las 15:20
  • @OscarRyz El mayor cambio para mí es que NIO te permite escuchar muchos puertos sin asignar un hilo para cada uno. No es un problema a menos que desee enviar un paquete a cada máquina en un espacio de direcciones de red de clase B (65k direcciones) para ver qué existe, Windows se queda sin subprocesos en alrededor de 20k (descubrí esto resolviendo exactamente este problema: descubrimiento de un red de clase A / B, antes de NIO era difícil). Bill K 17/03/15 a las 16:40
1693

Leer todo el texto de un archivo

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

String content = Files.readString(path, StandardCharsets.US_ASCII);

Para las versiones entre Java 7 y 11, aquí hay un modismo 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 una extensión 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 Stream<String>. Nuevamente, este método tiene pérdidas porque los separadores de línea se eliminan. Si IOExceptionse encuentra un al leer el archivo, se incluye en un UncheckedIOException, ya Streamque no acepta lambdas que arrojan excepciones comprobadas.

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 que Streamtiene 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 usar el lines()método en BufferedReader.

Utilización de la memoria

El primer método, que conserva los saltos de línea, puede requerir temporalmente memoria varias veces el tamaño del archivo, porque durante un breve período de tiempo el contenido del archivo sin procesar (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, leer líneas, suele ser más eficiente en memoria, porque 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 puede ser de muchos gigabytes de RAM. El tercer método, usar a Stream<String>es una forma de hacer esto, si sus "registros" de entrada resultan ser líneas individuales. (Usar el readLine()método de BufferedReaderes el procedimiento equivalente 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 la plataforma predeterminada es lo que desea, pero son raros y debería poder justificar su elección.

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);

La plataforma predeterminada está disponible en 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, impedía que el archivo leído se eliminara hasta que el búfer mapeado fuera recolectado como basura. Puede ver la versión anterior a través del enlace "editado" en esta respuesta.

1
  • 36
    Nota: después de ejercitar un poco ese código, descubrí que no se puede eliminar de manera confiable el archivo inmediatamente después de leerlo con este método, lo que puede no ser un problema en algunos casos, pero no el mío. ¿Puede estar relacionado con este problema: bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715154 ? Finalmente fui con la propuesta de Jon Skeet que no sufre de este error. De todos modos, solo quería dar la información, para otras personas, por si acaso ...Sébastien Nussbaumer 19/08/10 a las 15:47
378

Si está dispuesto a utilizar una biblioteca externa, consulte Apache Commons IO (200 KB JAR). Contiene un org.apache.commons.io.FileUtils.readFileToString()método que le permite leer un todo Fileen un Stringcon una 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);
}
0
186

Una solución muy ajustada 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, con un bloque try-with-resources , que lo llamará scanner.close():

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 olvide importar java.ioy java.util.

Fuente: blog de Pat Niemeyer

2
  • 4
    \\ A funciona porque no hay "otro comienzo de archivo", por lo que de hecho está leyendo el último token ... que también es el primero. Nunca probé con \\ Z. También tenga en cuenta que puede leer cualquier cosa que sea legible, como archivos, flujos de entrada, canales ... A veces uso este código para leer desde la ventana de visualización de eclipse, cuando no estoy seguro de si estoy leyendo un archivo u otro. .sí, classpath me confunde. Pablo Grisafi 16 de septiembre de 2011 a las 20:16
  • 21
    Scanner implementa Closeable (invoca close en la fuente), por lo que, si bien es elegante, no debería ser una frase única. El tamaño predeterminado del búfer es 1024, pero Scanner aumentará el tamaño según sea necesario (consulte Scanner # makeSpace ())earcam 23/11/12 a las 9:43
144
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);

desde Java 7 puedes hacerlo de esta manera.

0
80

Si está buscando una alternativa que no involucre una biblioteca de terceros (por ejemplo, Commons I / O ), puede usar la clase Scanner :

private String readFile(String pathname) throws IOException {

    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int)file.length());        

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString();
    }
}
0
72

Guava tiene un método similar al de Commons IOUtils que Willi aus Rohr mencionó:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);

EDIT by PiggyPiglet
Files#toString está obsoleto y se debe eliminar Octobor 2019. En su lugar, use Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();

EDITAR por Oscar Reyes

Este es el código subyacente (simplificado) en la biblioteca citada:

InputStream in = new FileInputStream(file);
byte[] b  = new byte[file.length()];
int len = b.length;
int total = 0;

while (total < len) {
  int result = in.read(b, total, len - total);
  if (result == -1) {
    break;
  }
  total += result;
}

return new String( b , Charsets.UTF_8 );

Editar (por Jonik): Lo anterior no coincide con el código fuente de las versiones recientes de Guava. Para obtener la fuente actual, consulte las clases Files , CharStreams , ByteSource y CharSource en el paquete com.google.common.io .

2
  • Este código tiene conversión de long a int, lo que podría mostrar un comportamiento loco con archivos grandes. ¿Tiene espacios adicionales y dónde cierra el flujo de entrada? Mohamed Taher Alrefaie 22/04/13 a las 15:42
  • @MTA: la secuencia está cerrada, tenga en cuenta el uso de Closeren CharSource . El código de la respuesta no es la fuente actual de Guava. Jonik 29/12/2013 a las 13:19
57
import java.nio.file.Files;

.......

 String readFile(String filename) {
            File f = new File(filename);
            try {
                byte[] bytes = Files.readAllBytes(f.toPath());
                return new String(bytes,"UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
    }
1
  • 13
    o new String(Files.readAllBytes(Paths.get(filename)));:-)assafmo 6 de abril de 2013 a las 12:09
52

Si necesita un procesamiento de cadenas (procesamiento paralelo), Java 8 tiene la gran API Stream.

String result = Files.lines(Paths.get("file.txt"))
                    .parallel() // for parallel processing 
                    .map(String::trim) // to change line   
                    .filter(line -> line.length() > 2) // to filter some lines by a predicate                        
                    .collect(Collectors.joining()); // to join lines

Hay más ejemplos disponibles en muestras de JDK sample/lambda/BulkDataOperationsque se pueden descargar desde la página de descarga de Oracle Java SE 8

Otro ejemplo de un trazador de líneas

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));
0
51

Ese código normalizará los saltos de línea, que pueden ser o no lo que realmente desea hacer.

Aquí hay una alternativa que no hace eso, y que es (IMO) más simple de entender que el código NIO (aunque todavía se usa java.nio.charset.Charset):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // No real need to close the BufferedReader/InputStreamReader
    // as they're only wrapping the stream
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Potential issue here: if this throws an IOException,
        // it will mask any others. Normally I'd use a utility
        // method which would log exceptions and swallow them
        stream.close();
    }        
}
2
  • 1
    Perdóname por revivir un comentario tan antiguo, pero ¿pretendías pasar un objeto String llamado "archivo", o debería ser un objeto File en su lugar? Bryan Larson 5/0613 a las 19:17
  • 1
    Gran respuesta. +1. Pero esta respuesta tiene 12 años. Java ahora tiene try-with-resources. Harshal Parekh 10/11/20 a las 20:32
30

Reunió todas las formas posibles de leer el archivo como cadena desde el disco o la red.

  • Guayaba: Google usando clases Resources,Files

    static Charset charset = com.google.common.base.Charsets.UTF_8;
    public static String guava_ServerFile( URL url ) throws IOException {
        return Resources.toString( url, charset );
    }
    public static String guava_DiskFile( File file ) throws IOException {
        return Files.toString( file, charset );
    }
    

  • APACHE - COMMONS IO usando clases IOUtils, FileUtils

    static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
    public static String commons_IOUtils( URL url ) throws IOException {
        java.io.InputStream in = url.openStream();
        try {
            return IOUtils.toString( in, encoding );
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
    public static String commons_FileUtils( File file ) throws IOException {
        return FileUtils.readFileToString( file, encoding );
        /*List<String> lines = FileUtils.readLines( fileName, encoding );
        return lines.stream().collect( Collectors.joining("\n") );*/
    }
    

  • Java 8 BufferReader usando Stream API

    public static String streamURL_Buffer( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
        //List<String> lines = reader.lines().collect( Collectors.toList() );
        return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
    }
    public static String streamFile_Buffer( File file ) throws IOException {
        BufferedReader reader = new BufferedReader( new FileReader( file ) );
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    }
    

  • Clase de escáner con expresiones regulares \A. que coincide con el comienzo de la entrada.

    static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
    public static String streamURL_Scanner( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        Scanner scanner = new Scanner(source, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    public static String streamFile_Scanner( File file ) throws IOException {
        Scanner scanner = new Scanner(file, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    

  • Java 7 ( java.nio.file.Files.readAllBytes)

    public static String getDiskFile_Java7( File file ) throws IOException {
        byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
        return new String( readAllBytes );
    }
    

  • BufferedReaderusando InputStreamReader.

    public static String getDiskFile_Lines( File file ) throws IOException {
        StringBuffer text = new StringBuffer();
        FileInputStream fileStream = new FileInputStream( file );
        BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );
        for ( String line; (line = br.readLine()) != null; )
            text.append( line + System.lineSeparator() );
        return text.toString();
    }
    

Ejemplo con método principal para acceder a los métodos anteriores.

public static void main(String[] args) throws IOException {
    String fileName = "E:/parametarisation.csv";
    File file = new File( fileName );

    String fileStream = commons_FileUtils( file );
            // guava_DiskFile( file );
            // streamFile_Buffer( file );
            // getDiskFile_Java7( file );
            // getDiskFile_Lines( file );
    System.out.println( " File Over Disk : \n"+ fileStream );


    try {
        String src = "https://code.jquery.com/jquery-3.2.1.js";
        URL url = new URL( src );

        String urlStream = commons_IOUtils( url );
                // guava_ServerFile( url );
                // streamURL_Scanner( url );
                // streamURL_Buffer( url );
        System.out.println( " File Over Network : \n"+ urlStream );
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

@ver

26

Si es un archivo de texto, ¿por qué no usar apache commons-io ?

Tiene el siguiente método

public static String readFileToString(File file) throws IOException

Si desea las líneas como una lista, utilice

public static List<String> readLines(File file) throws IOException
0
25

Desde JDK 11:

String file = ...
Path path = Paths.get(file);
String content = Files.readString(path);
// Or readString(path, someCharset), if you need a Charset different from UTF-8
3
  • ¿Por qué, oh por qué, introducir nuevos métodos que se basan en el juego de caracteres predeterminado en 2018? mryan 24 de septiembre de 2018 a las 7:49
  • 2
    @mryan este método no se basa en el juego de caracteres predeterminado del sistema. Por defecto es UTF-8, eso está bien. leventov 24 sep 2018 a las 11:39
  • @leventov, ¡tienes razón! ¡también Files.readAllLines! eso hace que la API de archivos no sea muy consistente con los métodos anteriores, pero es para mejor :)mryan 25 de septiembre de 2018 a las 13:34
17

Para leer un archivo como binario y convertirlo al final

public static String readFileAsString(String filePath) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
    try {
        long len = new File(filePath).length();
        if (len > Integer.MAX_VALUE) throw new IOException("File "+filePath+" too large, was "+len+" bytes.");
        byte[] bytes = new byte[(int) len];
        dis.readFully(bytes);
        return new String(bytes, "UTF-8");
    } finally {
        dis.close();
    }
}
0
16

Con Java 7, esta es mi opción preferida para leer un archivo UTF-8:

String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");

Desde Java 7, el JDK tiene la nueva java.nio.fileAPI, que proporciona muchos accesos directos, por lo que no siempre se requieren bibliotecas de terceros para operaciones de archivos simples.

15

Java intenta ser extremadamente general y flexible en todo lo que hace. Como resultado, algo que es relativamente simple en un lenguaje de programación (su código sería reemplazado por " open(file).read()" en Python) es mucho más complicado. No parece haber una forma más corta de hacerlo, excepto usando una biblioteca externa (como lo mencionó Willi aus Rohr ). Sus opciones:

  • Utilice una biblioteca externa.
  • Copie este código en todos sus proyectos.
  • Cree su propia minibiblioteca que contiene las funciones que usa con frecuencia.

Su mejor apuesta es probablemente la segunda, ya que tiene la menor cantidad de dependencias.

3
  • 4
    Yeap. Hace que el lenguaje de nivel "alto" tenga un significado diferente. Java es de alto nivel en comparación con C pero bajo en comparación con Python o RubyOscarRyz 28 de nov. De 2008 a las 19:36
  • 3
    De acuerdo en que Java es largo en abstracciones de alto nivel pero corto en métodos de convenienciaDónal 11 de mayo de 2011 a las 16:44
  • 3
    Es cierto que Java tiene una cantidad increíble de formas de manejar archivos y muchas de ellas parecen complicadas. Pero esto está bastante cerca de lo que tenemos en lenguajes de nivel superior:byte[] bytes = Files.readAllBytes(someFile.toPath());Thorn 16/04/13 a las 20:45
11

Utilizando JDK 8 o superior:

no se utilizan bibliotecas externas

Puede crear un nuevo objeto String a partir del contenido del archivo (usando clases del java.nio.filepaquete):

public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}
1
  • Duplicado de la respuesta de Moritz Petersen que escribió: String content = new String (Files.readAllBytes (Paths.get (nombre de archivo)), "UTF-8"); Jean-Christophe Blanchard 29 nov 2018 a las 10:30
7

Hay una variación en el mismo tema que usa un bucle for, en lugar de un bucle while, para limitar el alcance de la variable de línea. Si es "mejor" es una cuestión de gusto personal.

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}
2
  • 3
    Esto cambiará las líneas nuevas a la opción de línea nueva predeterminada. Esto puede ser deseable o involuntario. Peter Lawrey 18/04/10 a las 7:23
  • Revirtió la edición a esta respuesta porque el objetivo era reducir el alcance de la linevariable. La edición lo declaró dos veces, lo que sería un error de compilación. Dan Dyer 1 de agosto de 2013 a las 20:16
7

Si no tiene acceso a la Filesclase, puede usar una solución nativa.

static String readFile(File file, String charset)
        throws IOException
{
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[fileInputStream.available()];
    int length = fileInputStream.read(buffer);
    fileInputStream.close();
    return new String(buffer, 0, length, charset);
}
1
  • ejemplo de juego de caracteres para invocar? Thufir 30 de diciembre de 2018 a las 8:48
4

Una solución flexible que utiliza IOUtils de Apache commons-io en combinación con StringWriter :

Reader input = new FileReader();
StringWriter output = new StringWriter();
try {
  IOUtils.copy(input, output);
} finally {
  input.close();
}
String fileContents = output.toString();

Funciona con cualquier lector o flujo de entrada (no solo con archivos), por ejemplo, al leer desde una URL.

3

Tenga en cuenta que el uso fileInputStream.available()del número entero devuelto no tiene que representar el tamaño real del archivo, sino la cantidad estimada de bytes que el sistema debería poder leer de la secuencia sin bloquear la E / S. Una forma segura y sencilla podría verse así

public String readStringFromInputStream(FileInputStream fileInputStream) {
    StringBuffer stringBuffer = new StringBuffer();
    try {
        byte[] buffer;
        while (fileInputStream.available() > 0) {
            buffer = new byte[fileInputStream.available()];
            fileInputStream.read(buffer);
            stringBuffer.append(new String(buffer, "ISO-8859-1"));
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) { }
    return stringBuffer.toString();
}

Debe tenerse en cuenta que este enfoque no es adecuado para codificaciones de caracteres multibyte como UTF-8.

1
  • 1
    Este código puede dar resultados impredecibles. De acuerdo con la documentación del available()método, no hay garantía de que se alcance el final del archivo en caso de que el método devuelva 0. En ese caso, podría terminar con un archivo incompleto. Lo que es peor, la cantidad de bytes realmente leídos puede ser menor que el valor devuelto por available(), en cuyo caso la salida se corrompe. wau 15 de marzo de 2013 a las 13:32
3

Este usa el método RandomAccessFile.readFully, ¡parece estar disponible desde JDK 1.0!

public static String readFileContent(String filename, Charset charset) throws IOException {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile(filename, "r");
        byte[] buffer = new byte[(int)raf.length()];
        raf.readFully(buffer);
        return new String(buffer, charset);
    } finally {
        closeStream(raf);
    }
} 


private static void closeStream(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException ex) {
            // do nothing
        }
    }
}
3

Puede probar la clase Scanner and File, una solución de pocas líneas

 try
{
  String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
  System.out.println(content);
}
catch(FileNotFoundException e)
{
  System.out.println("not found!");
}
3

Según la respuesta de @ erickson, puede usar:

public String readAll(String fileName) throws IOException {
    List<String> lines = Files.readAllLines(new File(fileName).toPath());
    return String.join("\n", lines.toArray(new String[lines.size()]));
}
3

Usuario java.nio.Filespara leer todas las líneas del archivo.

public String readFile() throws IOException {
        File fileToRead = new File("file path");
        List<String> fileLines = Files.readAllLines(fileToRead.toPath());
        return StringUtils.join(fileLines, StringUtils.EMPTY);
}
3
public static String slurp (final File file)
throws IOException {
    StringBuilder result = new StringBuilder();

    BufferedReader reader = new BufferedReader(new FileReader(file));

    try {
        char[] buf = new char[1024];

        int r = 0;

        while ((r = reader.read(buf)) != -1) {
            result.append(buf, 0, r);
        }
    }
    finally {
        reader.close();
    }

    return result.toString();
}
3
  • Creo que esto tiene el inconveniente de usar la codificación predeterminada de la plataforma. +1 de todos modos :)OscarRyz 9 feb 10 a las 15:53
  • 7
    Me parece que el bloque finalmente no conoce las variables definidas en el bloque try. javac 1.6.0_21 arroja el error cannot find symbol. ceving 25/06/12 a las 16:11
  • ¿Has probado tu propio código? Ha definido el lector en el bloque try / catch, por lo que no será accesible en el bloque finalmente. mauron85 31 oct 2018 a las 9:48
2

Todavía no puedo comentar otras entradas, así que lo dejaré aquí.

Una de las mejores respuestas aquí ( https://stackoverflow.com/a/326448/1521167 ):

private String readFile(String pathname) throws IOException {

File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");

try {
    while(scanner.hasNextLine()) {        
        fileContents.append(scanner.nextLine() + lineSeparator);
    }
    return fileContents.toString();
} finally {
    scanner.close();
}
}

todavía tiene un defecto. Siempre pone un nuevo carácter de línea al final de la cadena, lo que puede causar algunos errores extraños. Mi sugerencia es cambiarlo a:

    private String readFile(String pathname) throws IOException {
    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int) file.length());
    Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        if (scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine());
        }
        while (scanner.hasNextLine()) {
            fileContents.append(lineSeparator + scanner.nextLine());
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}
1
  • En el primer caso, es posible que esté agregando una nueva línea adicional al final. en el segundo caso, podría estar omitiendo uno. Entonces ambos están igualmente equivocados. Vea este artículoPatrick Parker 28/03/18 a las 13:46
2

Después de Ctrl + F'ing después de Scanner, creo que la solución Scanner también debería aparecer en la lista. De la manera más fácil de leer, dice así:

public String fileToString(File file, Charset charset) {
  Scanner fileReader = new Scanner(file, charset);
  fileReader.useDelimiter("\\Z"); // \Z means EOF.
  String out = fileReader.next();
  fileReader.close();
  return out;
}

Si usa Java 7 o más reciente (y realmente debería) considere usar try-with-resources para que el código sea más fácil de leer. No más cosas con puntos de cierre ensuciando todo. Pero esa es principalmente una elección estilística, me parece.

Estoy publicando esto principalmente para completar, ya que si necesita hacer esto mucho, debería haber cosas en java.nio.file.Files que deberían hacer el trabajo mejor.

Mi sugerencia sería usar Files # readAllBytes (Path) para tomar todos los bytes, y alimentarlo a un nuevo String (byte [] Charset) para obtener un String en el que pueda confiar. Los conjuntos de caracteres serán malos contigo durante tu vida, así que ten cuidado con esto ahora.

Otros han dado código y esas cosas, y no quiero robarles su gloria. ;)

2

Usando esta biblioteca , es una línea:

String data = IO.from(new File("data.txt")).toString();
1
  • 1
    si no se cuentan las líneas dentro de la biblioteca. Ari 1 de agosto de 2017 a las 2:13
2

Además, si su archivo está dentro de un frasco, también puede usar esto:

public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}

La ruta debe comenzar con, / por ejemplo, si su jar es

my.jar/com/some/thing/a.txt

Entonces quieres invocarlo así:

String myTxt = fromFileInJar("/com/com/thing/a.txt");
2

En una línea (Java 8), suponiendo que tenga un lector:

String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));