在Java中读取资源文本文件到字符串

是否有一种方法将资源中的文本文件读入字符串?

我想这是一个普遍的需求,但我在谷歌上找不到任何实用工具。

290870 次浏览

是的,番石榴Resources类中提供了这个。例如:

URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);

使用Apache commons的FileUtils。它有一个方法readFileToString

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

番石榴有一个"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);

此方法不要求文件在类路径中(如Jon双向飞碟前面的答案)。

如果你想逐行返回List<String>值,Guava也有Files.readLines():

List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);

请参考在这里比较从文本文件中获得String的3种方法(BufferedReader vs. Guava的Files vs. Guava的Resources)。

我自己也经常遇到这个问题。为了避免对小项目的依赖,我经常 当我不需要commons 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作为其原生文件编码(例如);因此,在 在这种情况下,您永远不知道目标编码,因此显式 编码信息是至关重要的。 此外,逐字符读取文件的循环似乎效率很低,但它用于 BufferedReader,非常快

你可以使用旧的愚蠢的扫描仪技巧联机程序来做到这一点,而不需要任何额外的依赖,如guava:

String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();

伙计们,除非你真的需要,否则不要用第三方的东西。JDK中已经有很多功能了。

yegor256找到了一个使用Apache Commons IO的很好的解决方案:

import org.apache.commons.io.IOUtils;


String text = IOUtils.toString(this.getClass().getResourceAsStream("foo.xml"),
"UTF-8");

对于java 7:

new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));

对于Java 11:

Files.readString(Paths.get(getClass().getResource("foo.txt").toURI()));

您可以使用下面的Java代码

new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));

如果你想从项目资源中获取你的字符串,比如文件 testcase / foo。在项目的src/main/resources中,执行以下操作:

String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));

请注意,在其他一些示例中缺少getClassLoader()方法。

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");

通过一组静态导入,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

我使用以下语句从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() : "";
}
}
}

不需要第三方依赖。

下面是我的方法

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
}
}

纯粹而简单,jar友好的Java 8+解决方案

如果你使用的是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用于其他任务,否则将这些库添加到项目中只是为了能够从文件中读取,这似乎有点过分。

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 common -io 2.5中,IOUtils.toString()方法支持URI参数,并返回位于类路径上的jar中的文件内容:

IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)

如果你有番石榴,那么你可以使用:

String fileContent = Files.asCharSource(new File(filename), Charset.forName("UTF-8")).read();

(其他解决方案提到了番石榴的其他方法,但已弃用)

下面的代码对我有用:

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的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-dependency静态方法:

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通用utils来处理这种类型的东西,并且在测试时广泛使用这种确切的用例(从类路径读取文件),特别是从/src/test/resources读取JSON文件作为单元/集成测试的一部分。如。

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 ...
}

我喜欢akosicki用愚蠢的扫描仪技巧回答的问题。这是我在Java 8(实际上一直追溯到Java 5)中看到的最简单的没有外部依赖的答案。这里有一个更简单的答案如果你能使用Java 9或更高版本(因为InputStream.readAllBytes()是在Java 9中添加的):

String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt")
.readAllBytes());