Apakah ada utilitas yang membantu untuk membaca file teks di sumber menjadi String. Saya kira ini adalah persyaratan yang populer, tetapi saya tidak dapat menemukan utilitas apa pun setelah Googling.
Apakah ada utilitas yang membantu untuk membaca file teks di sumber menjadi String. Saya kira ini adalah persyaratan yang populer, tetapi saya tidak dapat menemukan utilitas apa pun setelah Googling.
Jawaban:
Ya, Guava menyediakan ini di Resources
kelas. Sebagai contoh:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
menggunakan Resource.class.getClassLoader
tetapi dalam aplikasi web, ini mungkin bukan "Anda" loader kelas, jadi disarankan (misalnya dalam [1]) untuk menggunakan Thread.currentThread().getContextClassLoader().getResourceAsStream
sebagai gantinya (referensi [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
yang menjamin penggunaan loader kelas yang benar.
com.google.common.io.Resources
ditandai tidak stabil menurut SonarQube
guava
telah mengubah implementasinya. Untuk jambu 23 implementasinya suka mengikuti. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Anda dapat menggunakan oneliner trik Stupid Scanner tua untuk melakukannya tanpa ketergantungan tambahan seperti jambu biji:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Kawan, jangan gunakan barang pihak ketiga kecuali Anda benar-benar membutuhkannya. Sudah banyak fungsi di JDK.
CartApplication.class.getResourceAsStream
untuk CartApplication.class.getClassLoader().getResourceAsStream
memuat sumber daya di toples saat ini..seperti srm / test / resource
Untuk java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
tetapi sebaliknya solusi hebat!
Metode sederhana di bawah ini akan baik-baik saja jika Anda menggunakan Java 8 atau lebih tinggi:
/**
* 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()));
}
}
}
Dan itu juga berfungsi dengan sumber daya dalam file jar .
Tentang penyandian teks: InputStreamReader
akan menggunakan charset sistem default jika Anda tidak menentukannya. Anda mungkin ingin menentukannya sendiri untuk menghindari masalah decoding, seperti ini:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Selalu lebih suka tidak bergantung pada perpustakaan besar dan gemuk. Kecuali jika Anda sudah menggunakan Guava atau Apache Commons IO untuk tugas-tugas lain, menambahkan pustaka-pustaka itu ke proyek Anda hanya untuk dapat membaca dari sebuah file sepertinya terlalu banyak.
Saya mengerti bahwa Java murni tidak melakukan pekerjaan dengan baik ketika melakukan tugas-tugas sederhana seperti ini. Misalnya, ini adalah cara kami membaca dari file di Node.js:
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
Sederhana dan mudah dibaca (walaupun orang masih suka mengandalkan banyak dependensi, sebagian besar karena ketidaktahuan). Atau dengan Python:
with open('some-file.txt', 'r') as f:
content = f.read()
Ini menyedihkan, tetapi masih sederhana untuk standar Java dan yang harus Anda lakukan adalah menyalin metode di atas untuk proyek Anda dan menggunakannya. Saya bahkan tidak meminta Anda untuk memahami apa yang terjadi di sana, karena itu benar-benar tidak masalah bagi siapa pun. Itu hanya berfungsi, titik :-)
InputStream
variabel is
adalah null
atau tidak.
Guava memiliki metode "toString" untuk membaca file menjadi sebuah 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);
Metode ini tidak memerlukan file berada di classpath (seperti dalam jawaban Jon Skeet sebelumnya).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256 telah menemukan solusi yang bagus menggunakan 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()
ke rantai metode: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
apache-commons-io memiliki nama utilitas FileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
Saya sendiri sering mengalami masalah ini. Untuk menghindari ketergantungan pada proyek-proyek kecil, saya sering menulis fungsi utilitas kecil ketika saya tidak memerlukan commons io atau semacamnya. Berikut adalah kode untuk memuat konten file dalam buffer string:
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());
Menentukan pengkodean adalah penting dalam hal ini, karena Anda mungkin telah diedit file Anda dalam UTF-8, dan kemudian memasukkannya ke dalam toples, dan komputer yang membuka file tersebut mungkin memiliki CP-1251 sebagai file encoding asli (misalnya) ; jadi dalam hal ini Anda tidak pernah tahu target encoding, oleh karena itu informasi encoding eksplisit sangat penting. Juga loop untuk membaca file char oleh char tampaknya tidak efisien, tetapi digunakan pada BufferedReader, dan sebenarnya cukup cepat.
Anda dapat menggunakan kode berikut dari Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Jika Anda ingin mendapatkan String dari sumber daya proyek seperti file testcase / foo.json di src / main / resources di proyek Anda, lakukan ini:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Perhatikan bahwa metode getClassLoader () tidak ada pada beberapa contoh lainnya.
Gunakan FileUtils Apache commons. Ini memiliki metode readFileToString
Saya menggunakan berikut ini untuk membaca file sumber daya dari 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() : "";
}
}
}
Tidak diperlukan dependensi pihak ketiga.
Dengan set impor statis, solusi Guava bisa sangat kompak satu-liner:
toString(getResource("foo.txt"), UTF_8);
Diperlukan impor berikut:
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;
}
}
Setidaknya pada Apache commons-io 2.5, metode IOUtils.toString () mendukung argumen URI dan mengembalikan konten file yang terletak di dalam guci di classpath:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Saya suka jawaban akosicki dengan Trik Pemindai Bodoh. Ini yang paling sederhana yang saya lihat tanpa dependensi eksternal yang berfungsi di Java 8 (dan sebenarnya semua jalan kembali ke Java 5). Inilah jawaban yang bahkan lebih sederhana jika Anda dapat menggunakan Java 9 atau lebih tinggi (sejak InputStream.readAllBytes()
ditambahkan di Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
Jambu juga memiliki Files.readLines()
jika Anda ingin nilai kembali sebagai List<String>
baris-demi-baris:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Silakan merujuk ke sini untuk membandingkan 3 cara ( BufferedReader
vs Jambu biji Files
vs Jambu biji Resources
) untuk mendapatkan String
dari file teks.
Charsets
juga ada di Guava. Lihat ini: google.github.io/guava/releases/23.0/api/docs
Inilah pendekatan saya yang bekerja dengan baik
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
}
}
Saya telah menulis metode readResource () di sini , untuk dapat melakukannya dalam satu permintaan sederhana. Itu tergantung pada perpustakaan Guava, tapi saya suka metode JDK saja yang disarankan dalam jawaban lain dan saya pikir saya akan mengubahnya seperti itu.
Berikut ini solusi menggunakan 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);
}
}
Saya membuat metode statis NO-dependensi seperti ini:
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
}
Saya menyukai utilitas commons Apache untuk jenis barang ini dan menggunakan case-use yang tepat ini (membaca file dari classpath) secara luas saat pengujian, terutama untuk membaca file JSON dari /src/test/resources
sebagai bagian dari unit / pengujian integrasi. misalnya
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);
}
}
}
Untuk tujuan pengujian, akan lebih baik untuk menangkap IOException
dan melempar RuntimeException
- kelas tes Anda bisa terlihat seperti misalnya
@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");