มียูทิลิตีใด ๆ ที่ช่วยในการอ่านไฟล์ข้อความในทรัพยากรลงใน String หรือไม่ ฉันคิดว่านี่เป็นข้อกำหนดที่ได้รับความนิยม แต่ฉันไม่พบโปรแกรมอรรถประโยชน์ใด ๆ หลังจาก Googling
มียูทิลิตีใด ๆ ที่ช่วยในการอ่านไฟล์ข้อความในทรัพยากรลงใน String หรือไม่ ฉันคิดว่านี่เป็นข้อกำหนดที่ได้รับความนิยม แต่ฉันไม่พบโปรแกรมอรรถประโยชน์ใด ๆ หลังจาก Googling
คำตอบ:
ใช่ฝรั่งให้สิ่งนี้ในResources
ชั้นเรียน ตัวอย่างเช่น:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
อยู่Resource.class.getClassLoader
แต่ในเว็บแอปพลิเคชันนี่อาจไม่ใช่ "class" ของคุณดังนั้นจึงแนะนำให้ใช้ (เช่นใน [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
มีการเปลี่ยนแปลงการใช้งาน สำหรับฝรั่ง 23 การใช้งานมีดังต่อไปนี้ ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
คุณสามารถใช้กลโกง Stupid Scanner oneliner แบบเดิมโดยไม่ต้องพึ่งพาเพิ่มเติมเช่นฝรั่ง:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
ผู้ชายอย่าใช้สิ่งของบุคคลที่ 3 เว้นแต่คุณจะต้องการมัน มีฟังก์ชั่นมากมายใน JDK อยู่แล้ว
CartApplication.class.getResourceAsStream
ไปCartApplication.class.getClassLoader().getResourceAsStream
โหลดทรัพยากรในปัจจุบัน jar..like SRM / ทดสอบ / ทรัพยากร
สำหรับ 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);
มักจะไม่ชอบขึ้นอยู่กับห้องสมุดขนาดใหญ่และอ้วน นอกจากว่าคุณกำลังใช้ Guava หรือ Apache Commons IO อยู่แล้วสำหรับงานอื่น ๆ การเพิ่มไลบรารีเหล่านั้นในโครงการของคุณเพื่อให้สามารถอ่านจากไฟล์ดูเหมือนจะมากเกินไป
ฉันเข้าใจว่า pure 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" สำหรับการอ่านไฟล์ลงใน 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);
วิธีนี้ไม่ต้องการให้ไฟล์อยู่ใน classpath (เช่นเดียวกับคำตอบก่อนหน้านี้ของJon Skeet )
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256พบทางออกที่ดีโดยใช้ 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()
วิธีห่วงโซ่: 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
ฉันมักจะมีปัญหานี้ด้วยตนเอง เพื่อหลีกเลี่ยงการพึ่งพาโครงการขนาดเล็กฉันมักจะเขียนฟังก์ชั่นยูทิลิตี้ขนาดเล็กเมื่อฉันไม่ต้องการคอมมอน io นี่คือรหัสในการโหลดเนื้อหาของไฟล์ในสตริงบัฟเฟอร์:
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())));
หากคุณต้องการได้รับสตริงของคุณจากทรัพยากรโครงการเช่นไฟล์ testcase / foo.json ใน src / main / resources ในโครงการของคุณทำสิ่งนี้:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
โปรดสังเกตว่าเมธอด getClassLoader () หายไปในตัวอย่างอื่น
ใช้ FileUtils ของ 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 กับ Stupid Scanner Trick มันง่ายที่สุดที่ฉันเห็นโดยไม่ต้องพึ่งพาภายนอกที่ทำงานใน 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
Guava กับของ Guava Resources
) เพื่อรับString
จากไฟล์ข้อความ
Charsets
ยังอยู่ใน Guava เห็นนี้: 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 เท่านั้นที่แนะนำในคำตอบอื่น ๆ และฉันคิดว่าฉันจะเปลี่ยนสิ่งเหล่านี้
หากคุณรวม Guava คุณสามารถใช้:
String fileContent = Files.asCharSource(new File(filename), Charset.forName("UTF-8")).read();
(วิธีการแก้ปัญหาอื่น ๆ ที่กล่าวถึงวิธีอื่นสำหรับ Guava แต่พวกเขาจะเลิก
รหัสต่อไปนี้ใช้งานได้สำหรับฉัน:
compile group: 'commons-io', name: 'commons-io', version: '2.6'
@Value("classpath:mockResponse.json")
private Resource mockResponse;
String mockContent = FileUtils.readFileToString(mockResponse.getFile(), "UTF-8");
นี่เป็นวิธีแก้ปัญหาโดยใช้ Java 11's 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);
}
}
ฉันทำวิธีคงที่ไม่มีการพึ่งพาแบบนี้:
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");