Existe-t-il un utilitaire qui aide à lire un fichier texte dans la ressource dans une chaîne. Je suppose que c'est une exigence populaire, mais je n'ai trouvé aucun utilitaire après Google.
Existe-t-il un utilitaire qui aide à lire un fichier texte dans la ressource dans une chaîne. Je suppose que c'est une exigence populaire, mais je n'ai trouvé aucun utilitaire après Google.
Réponses:
Oui, Guava fournit cela en Resources
classe. Par exemple:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
utilise Resource.class.getClassLoader
mais dans les applications web, ce n'est peut-être pas "votre" chargeur de classe, il est donc recommandé (par exemple dans [1]) d'utiliser Thread.currentThread().getContextClassLoader().getResourceAsStream
à la place (référence [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
ce qui garantit l'utilisation du chargeur de classe correct.
com.google.common.io.Resources
est marqué comme instable selon SonarQube
guava
a changé la mise en œuvre. Pour la goyave 23, l'implémentation aime suivre. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Vous pouvez utiliser l'ancien onliner de Stupid Scanner pour le faire sans aucune dépendance supplémentaire comme la goyave:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Les gars, n'utilisez pas de trucs tiers sauf si vous en avez vraiment besoin. Il y a déjà beaucoup de fonctionnalités dans le JDK.
CartApplication.class.getResourceAsStream
pour CartApplication.class.getClassLoader().getResourceAsStream
charger les ressources dans le pot actuel .. comme srm / test / resources
Pour java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
mais sinon super solution!
Cette méthode simple ci-dessous fera très bien l'affaire si vous utilisez Java 8 ou supérieur:
/**
* Reads given resource file as a string.
*
* @param fileName path to the resource file
* @return the file's contents
* @throws IOException if read fails for any reason
*/
static String getResourceFileAsString(String fileName) throws IOException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try (InputStream is = classLoader.getResourceAsStream(fileName)) {
if (is == null) return null;
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}
}
}
Et cela fonctionne également avec des ressources dans des fichiers jar .
À propos de l'encodage de texte: InputStreamReader
utilisera le jeu de caractères système par défaut au cas où vous n'en spécifieriez pas un. Vous voudrez peut-être le spécifier vous-même pour éviter les problèmes de décodage, comme ceci:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Préférez toujours ne pas dépendre de grosses bibliothèques grasses. À moins que vous n'utilisiez déjà Guava ou Apache Commons IO pour d'autres tâches, ajouter ces bibliothèques à votre projet juste pour pouvoir lire à partir d'un fichier semble un peu trop.
Je comprends que Java pur ne fait pas du bon travail quand il s'agit de faire des tâches simples comme celle-ci. Par exemple, voici comment nous lisons à partir d'un fichier dans Node.js:
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
Simple et facile à lire (bien que les gens aiment toujours compter sur de nombreuses dépendances de toute façon, principalement en raison de l'ignorance). Ou en Python:
with open('some-file.txt', 'r') as f:
content = f.read()
C'est triste, mais c'est toujours simple pour les normes Java et tout ce que vous avez à faire est de copier la méthode ci-dessus dans votre projet et de l'utiliser. Je ne vous demande même pas de comprendre ce qui se passe là-dedans, car cela n'a vraiment d'importance pour personne. Cela fonctionne, point :-)
InputStream
variable is
est null
ou non.
Guava a une méthode "toString" pour lire un fichier dans une chaîne:
import com.google.common.base.Charsets;
import com.google.common.io.Files;
String content = Files.toString(new File("/home/x1/text.log"), Charsets.UTF_8);
Cette méthode ne nécessite pas que le fichier se trouve dans le chemin de classe (comme dans la réponse précédente de Jon Skeet ).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256 a trouvé une bonne solution en utilisant Apache Commons IO :
import org.apache.commons.io.IOUtils;
String text = IOUtils.toString(this.getClass().getResourceAsStream("foo.xml"),
"UTF-8");
IOUtils.toString(this.getClass().getResource("foo.xml"), "UTF-8")
.
getClassLoader()
à la chaîne de méthodes: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
apache-commons-io a un nom d'utilitaire FileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
J'ai souvent eu ce problème moi-même. Pour éviter les dépendances sur les petits projets, j'écris souvent une petite fonction utilitaire quand je n'ai pas besoin de communs io ou autres. Voici le code pour charger le contenu du fichier dans un tampon de chaîne:
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("path/to/textfile.txt"), "UTF-8"));
for (int c = br.read(); c != -1; c = br.read()) sb.append((char)c);
System.out.println(sb.toString());
La spécification de l'encodage est importante dans ce cas, car vous pourriez avoir modifié votre fichier en UTF-8, puis le mettre dans un bocal, et l'ordinateur qui ouvre le fichier peut avoir CP-1251 comme encodage de fichier natif (par exemple) ; dans ce cas, vous ne connaissez jamais le codage cible, par conséquent, les informations de codage explicites sont cruciales. La boucle pour lire le fichier char par char semble également inefficace, mais elle est utilisée sur un BufferedReader, et donc assez rapide.
Vous pouvez utiliser le code suivant Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Si vous souhaitez obtenir votre chaîne à partir d'une ressource de projet comme le fichier testcase / foo.json dans src / main / resources dans votre projet, procédez comme suit:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Notez que la méthode getClassLoader () est manquante dans certains des autres exemples.
Utilisez FileUtils d'Apache commons. Il a une méthode readFileToString
J'utilise ce qui suit pour lire les fichiers de ressources à partir de classpath
:
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Scanner;
public class ResourceUtilities
{
public static String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = ResourceUtilities.class.getClassLoader().getResourceAsStream(filePath))
{
return inputStreamToString(inputStream);
}
}
private static String inputStreamToString(InputStream inputStream)
{
try (Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"))
{
return scanner.hasNext() ? scanner.next() : "";
}
}
}
Aucune dépendance tierce n'est requise.
Avec un ensemble d'importations statiques, la solution de goyave peut être très compacte:
toString(getResource("foo.txt"), UTF_8);
Les importations suivantes sont requises:
import static com.google.common.io.Resources.getResource
import static com.google.common.io.Resources.toString
import static java.nio.charset.StandardCharsets.UTF_8
package test;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
String fileContent = getFileFromResources("resourcesFile.txt");
System.out.println(fileContent);
} catch (Exception e) {
e.printStackTrace();
}
}
//USE THIS FUNCTION TO READ CONTENT OF A FILE, IT MUST EXIST IN "RESOURCES" FOLDER
public static String getFileFromResources(String fileName) throws Exception {
ClassLoader classLoader = Main.class.getClassLoader();
InputStream stream = classLoader.getResourceAsStream(fileName);
String text = null;
try (Scanner scanner = new Scanner(stream, StandardCharsets.UTF_8.name())) {
text = scanner.useDelimiter("\\A").next();
}
return text;
}
}
Au moins à partir d'Apache commons-io 2.5, la méthode IOUtils.toString () prend en charge un argument URI et renvoie le contenu des fichiers situés à l'intérieur des jars sur le chemin de classe:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
J'aime la réponse d'Akosicki avec le Stupid Scanner Trick. C'est le plus simple que je vois sans dépendances externes qui fonctionne dans Java 8 (et en fait tout le chemin du retour à Java 5). Voici une réponse encore plus simple si vous pouvez utiliser Java 9 ou supérieur (car il a InputStream.readAllBytes()
été ajouté à Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
La goyave a aussi Files.readLines()
si vous voulez une valeur de retour List<String>
ligne par ligne:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Veuillez vous référer ici pour comparer 3 façons ( BufferedReader
vs Guava's Files
vs Guava's Resources
) d'obtenir String
d'un fichier texte.
Charsets
est également à Guava. Voir ceci: google.github.io/guava/releases/23.0/api/docs
Voici mon approche a bien fonctionné
public String getFileContent(String fileName) {
String filePath = "myFolder/" + fileName+ ".json";
try(InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath)) {
return IOUtils.toString(stream, "UTF-8");
} catch (IOException e) {
// Please print your Exception
}
}
J'ai écrit des méthodes readResource () ici , pour pouvoir le faire en une seule invocation simple. Cela dépend de la bibliothèque Guava, mais j'aime les méthodes JDK uniquement suggérées dans d'autres réponses et je pense que je vais les changer de cette façon.
Voici une solution utilisant Java 11 Files.readString
:
public class Utils {
public static String readResource(String name) throws URISyntaxException, IOException {
var uri = Utils.class.getResource("/" + name).toURI();
var path = Paths.get(uri);
return Files.readString(path);
}
}
J'ai créé une méthode statique sans dépendance comme celle-ci:
import java.nio.file.Files;
import java.nio.file.Paths;
public class ResourceReader {
public static String asString(String resourceFIleName) {
try {
return new String(Files.readAllBytes(Paths.get(new CheatClassLoaderDummyClass().getClass().getClassLoader().getResource(resourceFIleName).toURI())));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class CheatClassLoaderDummyClass{//cheat class loader - for sql file loading
}
J'aime les utilitaires communs Apache pour ce type de choses et j'utilise ce cas d'utilisation exact (lecture de fichiers depuis classpath) lors des tests, en particulier pour la lecture de fichiers JSON dans /src/test/resources
le cadre de tests unitaires / d'intégration. par exemple
public class FileUtils {
public static String getResource(String classpathLocation) {
try {
String message = IOUtils.toString(FileUtils.class.getResourceAsStream(classpathLocation),
Charset.defaultCharset());
return message;
}
catch (IOException e) {
throw new RuntimeException("Could not read file [ " + classpathLocation + " ] from classpath", e);
}
}
}
À des fins de test, il peut être agréable d'attraper IOException
et de lancer un RuntimeException
- votre classe de test pourrait ressembler, par exemple
@Test
public void shouldDoSomething () {
String json = FileUtils.getResource("/json/input.json");
// Use json as part of test ...
}
public static byte[] readResoureStream(String resourcePath) throws IOException {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
InputStream in = CreateBffFile.class.getResourceAsStream(resourcePath);
//Create buffer
byte[] buffer = new byte[4096];
for (;;) {
int nread = in.read(buffer);
if (nread <= 0) {
break;
}
byteArray.write(buffer, 0, nread);
}
return byteArray.toByteArray();
}
Charset charset = StandardCharsets.UTF_8;
String content = new String(FileReader.readResoureStream("/resource/...*.txt"), charset);
String lines[] = content.split("\\n");