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é?
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.
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:
com.google.common.io.Files
contient de nombreuses méthodes utiles. Les plus pertinents ici sont:
String toString(File, Charset)
String
.List<String> readLines(File, Charset)
List<String>
_, une entrée par ligneorg.Apache.commons.io.IOUtils
offre également des fonctionnalités similaires:
String toString(InputStream, String encoding)
InputStream
en tant que String
List readLines(InputStream, String encoding)
List
sur String
, une entrée par ligneDe 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.
Vous pouvez utiliser Apache commons IO ..
FileInputStream fisTargetFile = new FileInputStream(new File("test.txt"));
String targetFileStr = IOUtils.toString(fisTargetFile, "UTF-8");
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")));
}
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.
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 ...
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 ;-)
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.
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();