Gibt es ein Dienstprogramm, mit dem eine Textdatei in der Ressource in einen String eingelesen werden kann? Ich nehme an, dies ist eine beliebte Anforderung, aber ich konnte nach dem Googeln kein Dienstprogramm finden.
Gibt es ein Dienstprogramm, mit dem eine Textdatei in der Ressource in einen String eingelesen werden kann? Ich nehme an, dies ist eine beliebte Anforderung, aber ich konnte nach dem Googeln kein Dienstprogramm finden.
Antworten:
Ja, Guava bietet dies in der Resources
Klasse an. Beispielsweise:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
wird verwendet, Resource.class.getClassLoader
aber in Webanwendungen ist dies möglicherweise nicht "Ihr" Klassenladeprogramm, daher wird die Verwendung empfohlen (z. B. in [1]) Thread.currentThread().getContextClassLoader().getResourceAsStream
stattdessen (Referenz [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
, um die Verwendung des richtigen Klassenladeprogramms zu gewährleisten.
com.google.common.io.Resources
ist laut SonarQube
guava
hat die Implementierung geändert. Für Guave 23 mag die Implementierung Folgendes. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Sie können den alten Stupid Scanner Trick Oneliner verwenden, um dies ohne zusätzliche Abhängigkeit wie Guave zu tun:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Leute, benutzt keine Sachen von Drittanbietern, es sei denn, ihr braucht das wirklich. Das JDK bietet bereits viele Funktionen.
CartApplication.class.getResourceAsStream
zu CartApplication.class.getClassLoader().getResourceAsStream
, um Ressourcen in das aktuelle Glas zu laden. Wie srm / test / resources
Für Java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
aber sonst tolle Lösung!
Diese einfache Methode reicht aus, wenn Sie Java 8 oder höher verwenden:
/**
* 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()));
}
}
}
Und es funktioniert auch mit Ressourcen in JAR-Dateien .
Informationen zur Textcodierung: InputStreamReader
Verwendet den Standard-Systemzeichensatz, falls Sie keinen angeben. Sie können es selbst angeben, um Dekodierungsprobleme wie folgt zu vermeiden:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Immer lieber nicht abhängig von großen, fetten Bibliotheken. Sofern Sie Guava oder Apache Commons IO nicht bereits für andere Aufgaben verwenden, erscheint es etwas zu viel, diese Bibliotheken zu Ihrem Projekt hinzuzufügen, nur um aus einer Datei lesen zu können.
Ich verstehe, dass reines Java keine gute Arbeit leistet, wenn es darum geht, einfache Aufgaben wie diese zu erledigen. So lesen wir zum Beispiel aus einer Datei in Node.js:
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
Einfach und leicht zu lesen (obwohl sich die Leute sowieso immer noch gerne auf viele Abhängigkeiten verlassen, hauptsächlich aus Unwissenheit). Oder in Python:
with open('some-file.txt', 'r') as f:
content = f.read()
Es ist traurig, aber für Javas Standards immer noch einfach. Sie müssen lediglich die oben beschriebene Methode in Ihr Projekt kopieren und verwenden. Ich bitte Sie nicht einmal zu verstehen, was dort vor sich geht, weil es für niemanden wirklich wichtig ist. Es funktioniert einfach, Punkt :-)
InputStream
Variable is
ist null
oder nicht.
Guava hat eine "toString" -Methode zum Einlesen einer Datei in einen String:
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);
Für diese Methode muss sich die Datei nicht im Klassenpfad befinden (wie in der vorherigen Antwort von Jon Skeet ).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256 hat mit Apache Commons IO eine gute Lösung gefunden :
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()
der Methodenkette String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
apache-commons-io hat einen Dienstprogrammnamen FileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
Ich hatte dieses Problem oft selbst. Um Abhängigkeiten von kleinen Projekten zu vermeiden, schreibe ich oft eine kleine Dienstprogrammfunktion, wenn ich kein Commons io oder ähnliches benötige. Hier ist der Code zum Laden des Inhalts der Datei in einen Zeichenfolgenpuffer:
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());
In diesem Fall ist es wichtig, die Codierung anzugeben , da Sie Ihre Datei möglicherweise in UTF-8 bearbeitet und dann in eine JAR-Datei gestellt haben und der Computer, der die Datei öffnet, möglicherweise CP-1251 als native Dateicodierung hat (z. B.). ;; In diesem Fall kennen Sie die Zielcodierung nie. Daher sind die expliziten Codierungsinformationen von entscheidender Bedeutung. Auch die Schleife zum Lesen der Datei char by char scheint ineffizient zu sein, wird aber auf einem BufferedReader verwendet und ist daher eigentlich recht schnell.
Sie können das folgende Codeformular Java verwenden
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Wenn Sie Ihren String aus einer Projektressource wie der Datei testcase / foo.json in src / main / resources in Ihrem Projekt abrufen möchten, gehen Sie folgendermaßen vor:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Beachten Sie, dass die Methode getClassLoader () in einigen anderen Beispielen fehlt.
Verwenden Sie die FileUtils von Apache Commons. Es hat eine Methode readFileToString
Ich verwende Folgendes zum Lesen von Ressourcendateien aus 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() : "";
}
}
}
Keine Abhängigkeiten von Drittanbietern erforderlich.
Mit einer Reihe von statischen Importen kann die Guava-Lösung ein sehr kompakter Einzeiler sein:
toString(getResource("foo.txt"), UTF_8);
Folgende Importe sind erforderlich:
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;
}
}
Zumindest ab Apache commons-io 2.5 unterstützt die Methode IOUtils.toString () ein URI-Argument und gibt den Inhalt von Dateien zurück, die sich in Jars im Klassenpfad befinden:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Ich mag Akosickis Antwort mit dem dummen Scanner-Trick. Es ist das einfachste, das ich ohne externe Abhängigkeiten sehe, das in Java 8 funktioniert (und tatsächlich bis zurück zu Java 5). Hier ist eine noch einfachere Antwort, wenn Sie Java 9 oder höher verwenden können (da InputStream.readAllBytes()
es bei Java 9 hinzugefügt wurde):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
Guave hat auch, Files.readLines()
wenn Sie einen Rückgabewert als List<String>
Zeile für Zeile wünschen :
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Bitte lesen Sie hier , um 3 Möglichkeiten ( BufferedReader
gegen Guavas Files
gegen Guavas Resources
) zu vergleichen, um String
aus einer Textdatei zu gelangen .
Charsets
ist auch in Guave. Siehe dies: google.github.io/guava/releases/23.0/api/docs
Hier ist mein Ansatz gut funktioniert
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
}
}
Ich habe hier readResource () -Methoden geschrieben , um dies in einem einfachen Aufruf tun zu können. Es hängt von der Guava-Bibliothek ab, aber ich mag nur JDK-Methoden, die in anderen Antworten vorgeschlagen werden, und ich denke, ich werde diese auf diese Weise ändern.
Hier ist eine Lösung mit 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);
}
}
Ich habe eine statische Methode ohne Abhängigkeit wie folgt erstellt:
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
}
Ich mag Apache Commons-Utils für diese Art von Dingen und verwende diesen genauen Anwendungsfall (Lesen von Dateien aus dem Klassenpfad) ausgiebig beim Testen, insbesondere zum Lesen von JSON-Dateien /src/test/resources
im Rahmen von Unit- / Integrationstests. z.B
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);
}
}
}
Zu Testzwecken kann es schön sein, das zu fangen IOException
und ein zu werfen RuntimeException
- Ihre Testklasse könnte aussehen wie z
@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");