Lire tout le texte d'un fichier
Java 11 a ajouté la méthode readString () pour lire les petits fichiers en tant que String
, en préservant les terminateurs de ligne:
String content = Files.readString(path, StandardCharsets.US_ASCII);
Pour les versions entre Java 7 et 11, voici un idiome compact et robuste, enveloppé dans une méthode utilitaire:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Lire des lignes de texte à partir d'un fichier
Java 7 a ajouté une méthode pratique pour lire un fichier sous forme de lignes de texte, représentées par un List<String>
. Cette approche est "avec perte" car les séparateurs de ligne sont retirés de la fin de chaque ligne.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 a ajouté la Files.lines()
méthode pour produire un Stream<String>
. Encore une fois, cette méthode est avec perte car les séparateurs de ligne sont supprimés. Si un IOException
est rencontré lors de la lecture du fichier, il est enveloppé dans un UncheckedIOException
, car Stream
n'accepte pas les lambdas qui lèvent des exceptions vérifiées.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
Cela Stream
nécessite un close()
appel; cela est mal documenté sur l'API, et je soupçonne que beaucoup de gens ne remarquent même pas Stream
a une close()
méthode. Assurez-vous d'utiliser un bloc ARM comme indiqué.
Si vous travaillez avec une source autre qu'un fichier, vous pouvez utiliser la lines()
méthode dans à la BufferedReader
place.
Utilisation de la mémoire
La première méthode, qui préserve les sauts de ligne, peut temporairement nécessiter de la mémoire plusieurs fois la taille du fichier, car pendant une courte période le contenu brut du fichier (un tableau d'octets) et les caractères décodés (chacun de 16 bits même s'il est codé comme 8 bits dans le fichier) résident en mémoire à la fois. Il est plus sûr d'appliquer aux fichiers que vous savez être petits par rapport à la mémoire disponible.
La deuxième méthode, la lecture des lignes, est généralement plus efficace en mémoire, car le tampon d'octets d'entrée pour le décodage n'a pas besoin de contenir le fichier entier. Cependant, il n'est toujours pas adapté aux fichiers très volumineux par rapport à la mémoire disponible.
Pour lire des fichiers volumineux, vous avez besoin d'une conception différente pour votre programme, une qui lit un morceau de texte à partir d'un flux, le traite, puis passe au suivant, en réutilisant le même bloc de mémoire de taille fixe. Ici, "grand" dépend des spécifications de l'ordinateur. De nos jours, ce seuil peut être de plusieurs gigaoctets de RAM. La troisième méthode, en utilisant un, Stream<String>
est une façon de le faire, si vos «enregistrements» d'entrée se trouvent être des lignes individuelles. (En utilisant la readLine()
méthode deBufferedReader
est l'équivalent procédural de cette approche.)
Encodage de caractère
Une chose qui manque dans l'exemple de l'article d'origine est l'encodage des caractères. Il y a des cas spéciaux où la plate-forme par défaut est ce que vous voulez, mais ils sont rares, et vous devriez pouvoir justifier votre choix.
La StandardCharsets
classe définit quelques constantes pour les encodages requis pour tous les runtimes Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
La plate-forme par défaut est disponible dans la Charset
classe elle - même:
String content = readFile("test.txt", Charset.defaultCharset());
Remarque: Cette réponse remplace largement ma version Java 6. L'utilitaire de Java 7 simplifie le code en toute sécurité et l'ancienne réponse, qui utilisait un tampon d'octets mappés, empêchait la suppression du fichier lu jusqu'à ce que le tampon mappé soit récupéré. Vous pouvez voir l'ancienne version via le lien "édité" sur cette réponse.