Чи є якась утиліта, яка допомагає читати текстовий файл із ресурсу в String. Я вважаю, що це популярна вимога, але я не зміг знайти жодної утиліти після Googling.
Чи є якась утиліта, яка допомагає читати текстовий файл із ресурсу в String. Я вважаю, що це популярна вимога, але я не зміг знайти жодної утиліти після Googling.
Відповіді:
Так, Guava забезпечує це у Resources
класі. Наприклад:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
використовується, Resource.class.getClassLoader
але у веб-додатках це може бути не вашим завантажувачем класів, тому рекомендується (наприклад, у [1]) використовувати Thread.currentThread().getContextClassLoader().getResourceAsStream
натомість (посилання [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
що гарантує використання правильного завантажувача класів.
com.google.common.io.Resources
позначається нестабільним згідно з SonarQube
guava
змінила реалізацію. Для guava 23 реалізація любить наступне. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Ви можете використовувати старий хитромудрий сканер Oneliner, щоб зробити це без будь-якої додаткової залежності, як гуава:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Хлопці, не використовуйте сторонні речі, якщо вам це дуже не потрібно. У JDK вже багато функціональних можливостей.
CartApplication.class.getResourceAsStream
щоб CartApplication.class.getClassLoader().getResourceAsStream
завантажити ресурси в поточній банці. як srm / test / ресурси
Для java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
але в іншому випадку чудове рішення!
Цей простий метод нижче буде добре, якщо ви використовуєте Java 8 або новіші версії:
/**
* 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()));
}
}
}
А також він працює з ресурсами в jar-файлах .
Про кодування тексту: InputStreamReader
буде використано системну схему за замовчуванням у випадку, якщо ви її не вказали. Ви можете вказати його самостійно, щоб уникнути проблем із розшифровкою, наприклад:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Завжди віддайте перевагу не залежно від великих, жирних бібліотек. Якщо ви вже не використовуєте IO Guava або Apache Commons для інших завдань, додавання цих бібліотек до вашого проекту просто для того, щоб мати можливість читати з файлу, здається трохи занадто.
Я розумію, що чиста Java не робить гарної роботи, коли справа стосується виконання таких простих завдань. Наприклад, ось так ми читаємо з файлу в Node.js:
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
Простий і легкий для читання (хоча люди все одно люблять покладатися на багато залежностей, в основному через незнання). Або в Python:
with open('some-file.txt', 'r') as f:
content = f.read()
Це сумно, але для стандартів Java це все ще просто, і все, що вам потрібно зробити, - скопіювати вищевказаний метод у свій проект і використовувати його. Я навіть не прошу вас зрозуміти, що там відбувається, бо це нікому не важливо. Це просто працює, період :-)
InputStream
змінною чи ні. is
null
Guava має метод "toString" для читання файлу в рядку:
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);
Цей метод не вимагає, щоб файл знаходився в класі (як у попередній відповіді Джона Скета ).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256 знайшов хороше рішення за допомогою IO Apache Commons :
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()
до ланцюжка методів: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
apache-commons-io має назву утиліти FileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
Я часто сам мав цю проблему. Щоб уникнути залежностей від невеликих проектів, я часто пишу невелику функцію утиліти, коли мені не потрібні загальнодоступні повідомлення тощо. Ось код для завантаження вмісту файлу в буфер рядків:
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());
Визначення кодування є важливим у цьому випадку, оскільки ви, можливо, відредагували свій файл в UTF-8, а потім помістили його в банку, а комп'ютер, який відкриває файл, може мати CP-1251 як кодування його рідного файлу (наприклад) ; тому в цьому випадку ви ніколи не знаєте цільове кодування, тому явна інформація про кодування має вирішальне значення. Також цикл для читання файлу char за допомогою char виглядає неефективним, але він використовується на BufferedReader, і так насправді досить швидко.
Ви можете використовувати таку форму коду Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Якщо ви хочете отримати свій String з такого ресурсу проекту, як файл testcase / foo.json у src / main / ресурси вашого проекту, зробіть це:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Зауважте, що метод getClassLoader () відсутній у деяких інших прикладах.
Використовуйте файлові утиліти Apache Commons. Він має метод readFileToString
Я використовую наступне для читання файлів ресурсів із 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() : "";
}
}
}
Ніяких сторонніх залежностей не потрібно.
Завдяки набору статичного імпорту, рішення Guava може бути дуже компактним однолінійним:
toString(getResource("foo.txt"), UTF_8);
Необхідний наступний імпорт:
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;
}
}
Принаймні, як Apache commons-io 2.5, метод IOUtils.toString () підтримує аргумент URI і повертає вміст файлів, розташованих всередині банки на classpath:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Мені подобається відповідь akosicki за допомогою трюку дурного сканера. Це найпростіший, що я бачу без зовнішніх залежностей, який працює в Java 8 (і насправді весь шлях назад до Java 5). Ось ще простіша відповідь, якщо ви можете використовувати Java 9 або новішу версію (оскільки вона InputStream.readAllBytes()
була додана в Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
Guava також має, Files.readLines()
якщо ви хочете повернути значення як List<String>
рядкове за рядком:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Будь ласка, зверніться сюди, щоб порівняти 3 способи ( BufferedReader
проти Гуави Files
проти Гуави Resources
), щоб отримати String
з текстового файлу.
Charsets
також є в Гуаві . Дивіться це: google.github.io/guava/releases/23.0/api/docs
Ось мій підхід спрацював чудово
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
}
}
Тут я написав методи readResource () , щоб можна було це зробити одним простим викликом. Це залежить від бібліотеки Guava, але мені подобаються лише методи JDK, запропоновані в інших відповідях, і я думаю, що я зміню це таким чином.
Ось рішення за допомогою 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);
}
}
Я зробив статичний метод 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
}
Мені подобаються утиліти Apache для цього типу матеріалів і широко використовую цей точний приклад використання (читання файлів з classpath) під час тестування, особливо для читання файлів JSON /src/test/resources
в рамках тестування одиниці / інтеграції. напр
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);
}
}
}
З метою тестування може бути приємно зловити IOException
та кинути RuntimeException
- ваш тестовий клас може виглядати, наприклад,
@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");