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


Answers

Commons FileUtils.readFileToString :

public static String readFileToString(File file)
                       throws IOException

Lee el contenido de un archivo en una cadena utilizando la codificación predeterminada para la máquina virtual. El archivo siempre está cerrado.

Parámetros:

  • file - el archivo para leer, no debe ser nulo

Devoluciones: el contenido del archivo, nunca nulo

Lanza: - IOException - en caso de un error de E / S

Desde: Commons IO 1.3.1

El código utilizado (indirectamente) por esa clase es:

IOUtils.java bajo Apache License 2.0 .

public static long copyLarge(InputStream input, OutputStream output)
       throws IOException {
   byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
   long count = 0;
   int n = 0;
   while (-1 != (n = input.read(buffer))) {
       output.write(buffer, 0, n);
       count += n;
   }
   return count;
}

Es muy similar al utilizado por Ritche_W.

Question

He estado utilizando el modismo de abajo desde hace un tiempo. Y parece ser el más extendido, al menos en los sitios que he visitado.

¿Hay alguna 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();
    }
}



en java 8, hay una nueva clase

java.util.stream.Stream

Una secuencia representa una secuencia de elementos y admite diferentes tipos de operaciones para realizar cálculos sobre esos elementos

Leer más sobre esto:

Documentación de Oracle

Aquí un ejemplo:

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public Class ReadFile{
  public  static String readFile(String filePath) {
 StringBuilder  stringBuilder = new StringBuilder();
    String ls = System.getProperty("line.separator");
        try {

            try (Stream<String> lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {
                for (String line : (Iterable<String>) lines::iterator) {


                      stringBuilder.append(line);
                      stringBuilder.append(ls);


                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

      return stringBuilder.toString(); 


}

}



Para leer un archivo como binario y convertir 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();
    }
}



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 "";
    }



No puedo comentar otras entradas todavía, así que lo dejaré aquí.

Una de las mejores respuestas aquí ( https://.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 de weirds. 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();
    }
}



Existe una variación en el mismo tema que utiliza 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);
}



Puede probar la clase de escáner y archivo, algunas líneas de solución

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



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



Ese código normalizará los saltos de línea, que pueden o no ser lo que realmente quieres 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 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();
    }        
}



import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;
/**
 * A simple example program that reads a text file into a String using Files.lines and stream.
 */
public class ReadTextFileExample {
    public static void main(String[] args) throws IOException {
        String contents = Files.lines(Paths.get("c:\\temp\\testfile.txt")).collect(Collectors.joining("\n"));
        System.out.println(contents);
    }
}



Si no tiene acceso a los archivos, haga lo siguiente:

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



Tenga en cuenta que al usar fileInputStream.available() el entero devuelto no tiene que representar el tamaño real del archivo, sino la cantidad de bytes que el sistema debería poder leer de la transmisión sin bloquear el IO. Una manera segura y simple 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();
}

Se debe considerar que este enfoque no es adecuado para codificaciones de caracteres multibyte como UTF-8.




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 quieres usar las líneas como una lista

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



Usando esta biblioteca , es una línea:

String data = IO.from(new File("data.txt")).toString();