Czy jest jakieś narzędzie, które pomaga odczytać plik tekstowy z zasobu w łańcuch. Przypuszczam, że jest to popularne wymaganie, ale po Googlingu nie mogłem znaleźć żadnego narzędzia.
Czy jest jakieś narzędzie, które pomaga odczytać plik tekstowy z zasobu w łańcuch. Przypuszczam, że jest to popularne wymaganie, ale po Googlingu nie mogłem znaleźć żadnego narzędzia.
Odpowiedzi:
Tak, Guava zapewnia to w Resources
klasie. Na przykład:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
używa, Resource.class.getClassLoader
ale w aplikacjach internetowych może to nie być „twój” moduł ładujący, więc zaleca się (np. W [1]) użycie Thread.currentThread().getContextClassLoader().getResourceAsStream
zamiast tego (odniesienie [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
co gwarantuje użycie poprawnego modułu ładującego klasy.
com.google.common.io.Resources
jest oznaczony jako niestabilny zgodnie z SonarQube
guava
zmienił wdrożenie. W przypadku guava 23 wdrożenie lubi podążać. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Możesz użyć starej sztuczki Stupid Scanner oneliner, aby to zrobić bez dodatkowej zależności, takiej jak guava:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Chłopaki, nie używajcie rzeczy innych firm, chyba że naprawdę tego potrzebujecie. JDK ma już wiele funkcji.
CartApplication.class.getResourceAsStream
aby CartApplication.class.getClassLoader().getResourceAsStream
ładować zasoby w bieżącym słoju .. jak srm / test / resources
W przypadku java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
ale poza tym świetnego rozwiązania!
Ta prosta metoda poniżej będzie dobrze, jeśli używasz Java 8 lub nowszej:
/**
* 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()));
}
}
}
Działa również z zasobami w plikach jar .
Informacje o kodowaniu tekstu: InputStreamReader
użyje domyślnego zestawu znaków systemowych, jeśli go nie określisz. Możesz to określić samodzielnie, aby uniknąć problemów z dekodowaniem, takich jak:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Zawsze wolę nie polegać na dużych, grubych bibliotekach. O ile nie używasz już Guava lub Apache Commons IO do innych zadań, dodanie tych bibliotek do projektu, aby móc czytać z pliku, wydaje się trochę za dużo.
Rozumiem, że czysta Java nie wykonuje dobrej roboty, jeśli chodzi o wykonywanie prostych zadań takich jak ten. Na przykład tak czytamy z pliku w Node.js:
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
Prosty i łatwy do odczytania (chociaż ludzie nadal lubią polegać na wielu zależnościach, głównie z powodu niewiedzy). Lub w Pythonie:
with open('some-file.txt', 'r') as f:
content = f.read()
To smutne, ale nadal jest proste w stosunku do standardów Java i wystarczy, że skopiujesz powyższą metodę do swojego projektu i użyjesz jej. Nawet nie proszę o zrozumienie, co się tam dzieje, ponieważ to naprawdę nie ma znaczenia dla nikogo. To po prostu działa, kropka :-)
InputStream
zmienna is
jest, null
czy nie.
Guava ma metodę „toString” do odczytu pliku do ciągu:
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);
Ta metoda nie wymaga, aby plik znajdował się w ścieżce klasy (jak w poprzedniej odpowiedzi Jona Skeeta ).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256 znalazł fajne rozwiązanie przy użyciu 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()
do łańcucha metod: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
apache-commons-io ma nazwę narzędzia FileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
Często sam miałem ten problem. Aby uniknąć zależności od małych projektów, często piszę małą funkcję użyteczności, gdy nie potrzebuję wspólnych elementów. Oto kod, aby załadować zawartość pliku do bufora ciągów:
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());
Określenie kodowania jest w tym przypadku ważne, ponieważ mógłbyś edytować plik w UTF-8, a następnie umieścić go w słoiku, a komputer, który otwiera plik, może mieć CP-1251 jako rodzime kodowanie pliku (na przykład) ; więc w tym przypadku nigdy nie znasz kodowania docelowego, dlatego jawne informacje o kodowaniu są kluczowe. Również pętla do odczytu pliku char przez char wydaje się nieefektywna, ale jest używana w BufferedReader, a więc właściwie dość szybko.
Możesz użyć następującego kodu z Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Jeśli chcesz pobrać ciąg z zasobu projektu, takiego jak plik testcase / foo.json w pliku src / main / resources w projekcie, wykonaj następujące czynności:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Zauważ, że w niektórych innych przykładach brakuje metody getClassLoader ().
Użyj ApUll FileUtils. Ma metodę readFileToString
Używam następujących do odczytu plików zasobów z 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() : "";
}
}
}
Nie są wymagane żadne zależności stron trzecich.
Dzięki zestawowi importu statycznego rozwiązanie Guava może być bardzo kompaktowym jednowarstwowym:
toString(getResource("foo.txt"), UTF_8);
Wymagany jest następujący import:
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;
}
}
Przynajmniej od Apache commons-io 2.5 metoda IOUtils.toString () obsługuje argument URI i zwraca zawartość plików znajdujących się w słoikach na ścieżce klas:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Podoba mi się odpowiedź Akosickiego za pomocą Głupiego skanera. Jest to najprostszy, jaki widzę bez zewnętrznych zależności, który działa w Javie 8 (a właściwie aż do Java 5). Oto jeszcze prostsza odpowiedź, jeśli możesz używać języka Java 9 lub nowszego (ponieważ InputStream.readAllBytes()
został dodany w języku Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
Guava ma również, Files.readLines()
jeśli chcesz zwracać wartość jako List<String>
linia po linii:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Zapoznaj się z tutaj, aby porównać 3 sposoby (w BufferedReader
porównaniu do Guawy Files
i Guawy Resources
) w celu uzyskania String
z pliku tekstowego.
Charsets
jest także w Guava. Zobacz: google.github.io/guava/releases/23.0/api/docs
Oto moje podejście działało dobrze
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
}
}
Napisałem tutaj metody readResource () , aby móc to zrobić za pomocą jednego prostego wywołania. To zależy od biblioteki Guava, ale lubię metody tylko JDK sugerowane w innych odpowiedziach i myślę, że zmienię je w ten sposób.
Oto rozwiązanie wykorzystujące 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);
}
}
Stworzyłem metodę statyczną zależną od NO:
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
}
Lubię narzędzia Apache commons do tego typu rzeczy i używam dokładnie tego przypadku (odczytywanie plików ze ścieżki klas) podczas testowania, szczególnie do odczytywania plików JSON /src/test/resources
w ramach testów jednostkowych / integracyjnych. na przykład
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);
}
}
}
Do celów testowych miło jest złapać IOException
i rzucić RuntimeException
- Twoja klasa testowa może wyglądać np
@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");