web-dev-qa-db-fra.com

Quel est le moyen le plus simple de lire un fichier dans String?

J'essaie de lire un simple fichier texte dans une chaîne. Bien sûr, il existe le moyen habituel d’obtenir le flux d’entrée et de le parcourir avec readLine () et de lire le contenu dans String.

Après avoir fait cela des centaines de fois dans le passé, je me demandais simplement comment puis-je faire cela avec un minimum de lignes de code? N'y a-t-il pas quelque chose dans Java comme String fileContents = XXX.readFile(myFile/*File*/) .. plutôt quelque chose d'aussi simple?

Je sais qu'il existe des bibliothèques comme Apache Commons IO qui fournissent de telles simplifications ou même que je peux écrire une simple classe Util pour le faire. Mais tout ce que je me demande, c’est une opération si fréquente dont tout le monde a besoin, alors pourquoi Java ne fournit-t-il pas une fonction aussi simple? N'y a-t-il pas vraiment une seule méthode quelque part pour lire un fichier en chaîne avec un encodage par défaut ou spécifié?

252
Gopi

Oui, vous pouvez le faire en une seule ligne (bien que pour une manipulation robuste IOException vous ne voudriez pas).

_String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
System.out.println(content);
_

Ceci utilise un Java.util.Scanner , lui indiquant de délimiter l'entrée avec _\Z_, qui correspond à la fin de l'ancre de chaîne. En fin de compte, l’entrée a un jeton réel, le fichier entier, qui peut donc être lu avec un seul appel à next().

Il y a n constructeur qui prend un File et un _String charSetName_ (parmi beaucoup d'autres surcharges). Ces deux constructeurs peuvent lancer FileNotFoundException, mais comme toutes les méthodes Scanner, aucun IOException ne peut être projeté au-delà de ces constructeurs.

Vous pouvez interroger la Scanner elle-même à l'aide de la méthode ioException() si une IOException s'est produite ou non. Vous pouvez également vouloir explicitement close() la Scanner après avoir lu le contenu, il est donc préférable de stocker la référence Scanner dans une variable locale.

Voir également

Questions connexes


Options de la bibliothèque tierce

Pour être complet, voici quelques très bonnes options si vous avez ces bibliothèques tierces très réputées et très utiles:

goyave

com.google.common.io.Files contient de nombreuses méthodes utiles. Les plus pertinents ici sont:

Apache Commons/IO

org.Apache.commons.io.IOUtils offre également des fonctionnalités similaires:

  • String toString(InputStream, String encoding)
    • En utilisant le codage de caractères spécifié, récupère le contenu d'un InputStream en tant que String
  • List readLines(InputStream, String encoding)
    • ... en tant que (brut) List sur String, une entrée par ligne

Questions connexes

344
polygenelubricants

De Java 7 (Description de l'API) vous pouvez faire:

new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);

Où cheminFichier est une chaîne représentant le fichier à charger.

187
Jim

Vous pouvez utiliser Apache commons IO ..

FileInputStream fisTargetFile = new FileInputStream(new File("test.txt"));

String targetFileStr = IOUtils.toString(fisTargetFile, "UTF-8");
42
Rakesh Goyal

Cela devrait fonctionner pour vous:

import Java.io.IOException;
import Java.nio.file.Files;
import Java.nio.file.Paths;

public static void main(String[] args) throws IOException {
    String content = new String(Files.readAllBytes(Paths.get("abc.Java")));
}
31
DDas

Utilisation de Apache Commons IO .

import org.Apache.commons.io.FileUtils;

//...

String contents = FileUtils.readFileToString(new File("/path/to/the/file"), "UTF-8")

Vous pouvez voir de javadoc pour la méthode pour plus de détails.

22
cjungel

N'écrivez pas votre propre classe util pour faire cela - je vous recommanderais d'utiliser Guava , qui regorge de toutes sortes de qualités. Dans ce cas, vous voudrez soit la classe Files (si vous ne faites que lire un fichier) ou CharStreams pour une lecture plus générale. Il a des méthodes pour lire les données dans une liste de chaînes (readLines) ou totalement (toString).

Il a aussi des méthodes utiles similaires pour les données binaires. Et puis il y a le reste de la bibliothèque ...

Je conviens que c’est ennuyeux qu’il n’y ait rien de semblable dans les bibliothèques standard. Heck, le simple fait de pouvoir fournir un CharSet à un FileReader rendrait la vie un peu plus simple ...

10
Jon Skeet

Une autre approche alternative est:

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

Une autre option consiste à utiliser les utilitaires fournis dans les bibliothèques open source
http://commons.Apache.org/io/api-1.4/index.html?org/Apache/commons/io/IOUtils.html

Pourquoi Java ne fournit-il pas une API utilitaire aussi commune?
a) pour conserver les API génériques afin que le codage, la mise en mémoire tampon, etc. soient gérés par le programmeur.
b) oblige les programmeurs à travailler et écrit/partage les librairies utilitaires opensource: D ;-)

7
Bhuvan Gupta

Malheureusement non.

Je conviens que cette opération fréquente devrait avoir une implémentation plus facile que la copie d'une entrée ligne par ligne, mais vous devrez soit écrire une méthode d'assistance, soit utiliser une bibliothèque externe.

6
Nikita Rybak

J'ai découvert que la réponse acceptée ne fonctionnait pas toujours, car \\Z pouvait apparaître dans le fichier. Un autre problème est que, si vous ne disposez pas du jeu de caractères correct, de nombreuses imprévus peuvent se produire et empêcher le scanner de ne lire qu'une partie du fichier.

La solution consiste à utiliser un délimiteur dont vous êtes certain qu'il ne se produira jamais dans le fichier. Cependant, c'est théoriquement impossible. Ce que nous POUVONS faire, c’est utiliser un délimiteur qui a une si petite chance de se produire dans le fichier qu’il est négligeable: un tel délimiteur est un UUID , qui est supporté nativement en Java.

String content = new Scanner(file, "UTF-8")
    .useDelimiter(UUID.randomUUID().toString()).next();
1
wvdz