Comment créer une chaîne Java à partir du contenu d'un fichier?


Answers

Commons FileUtils.readFileToString :

public static String readFileToString(File file)
                       throws IOException

Lit le contenu d'un fichier dans une chaîne en utilisant le codage par défaut de la machine virtuelle. Le fichier est toujours fermé.

Paramètres:

  • file - le fichier à lire ne doit pas être nul

Retourne: le contenu du fichier, jamais null

Lève: - IOException - en cas d'erreur E / S

Depuis: Commons IO 1.3.1

Le code utilisé (indirectement) par cette classe est:

IOUtils.java sous licence Apache 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;
}

Il est très similaire à celui utilisé par Ritche_W.

Question

J'utilise l'idiome ci-dessous depuis quelque temps maintenant. Et il semble que ce soit le plus répandu, du moins sur les sites que j'ai visités.

Y at-il une meilleure / différente façon de lire un fichier dans une chaîne 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();
    }
}



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



en Java 8, il y a une nouvelle classe

java.util.stream.Stream

Un flux représente une séquence d'éléments et supporte différents types d'opérations pour effectuer des calculs sur ces éléments

Pour en savoir plus à ce sujet:

Documentation Oracle

Voici un exemple:

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


}

}



Je ne peux pas commenter d'autres entrées pour le moment, donc je vais juste laisser ici.

Une des meilleures réponses ici ( 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();
}
}

a toujours un défaut. Il met toujours un nouveau caractère de ligne à la fin de la chaîne, ce qui peut causer des bogues étranges. Ma suggestion est de le changer pour:

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



En utilisant cette bibliothèque , c'est une ligne:

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



Il existe une variation sur le même thème qui utilise une boucle for, au lieu d'une boucle while, pour limiter la portée de la variable ligne. Que ce soit «mieux» est une question de goût personnel.

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}



Si vous n'avez pas accès aux fichiers, procédez comme suit:

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



Pour lire un fichier en binaire et le convertir à la fin

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



Soyez conscient lors de l'utilisation de fileInputStream.available() l'entier retourné n'a pas à représenter la taille réelle du fichier, mais plutôt la quantité estimée d'octets que le système devrait être capable de lire dans le flux sans bloquer les E / S. Un moyen sûr et simple pourrait ressembler à ceci

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

Il convient de considérer que cette approche n'est pas adaptée aux codages de caractères multi-octets tels que UTF-8.




Si vous recherchez une alternative qui n'implique pas de bibliothèque tierce (par exemple E / S Commons ), vous pouvez utiliser la classe 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();
    }
}



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



Ce code va normaliser les sauts de ligne, ce qui peut être ou ne pas être ce que vous voulez vraiment faire.

Voici une alternative qui ne fait pas cela, et qui est (IMO) plus simple à comprendre que le code NIO (bien qu'il utilise encore 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();
    }        
}



Vous pouvez essayer la classe Scanner et File, une solution de quelques lignes

 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 c'est un fichier texte, pourquoi ne pas utiliser apache commons-io ?

Il a la méthode suivante

public static String readFileToString(File file) throws IOException

Si vous voulez utiliser les lignes comme une liste

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



Related