有没有办法将资源中的文本文件读入字符串?
我想这是一个流行的要求,但我在谷歌搜索后找不到任何实用工具。
您可以使用旧的愚蠢的扫描仪技巧 oneliner 来做到这一点,而无需像番石榴这样的任何额外依赖:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
伙计们,除非你真的需要,否则不要使用第 3 方的东西。 JDK 中已经有很多功能了。
如果您使用的是 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 来执行其他任务,否则将这些库添加到您的项目中只是为了能够从文件中读取似乎有点太多了。
对于 Java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
对于 Java 11:
Files.readString(Paths.get(getClass().getClassLoader().getResource("foo.txt").toURI()));
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
我喜欢 akosicki 的“愚蠢的扫描仪技巧”的回答。这是我看到的最简单的方法,不需要外部依赖,可以在 Java 8 中工作(实际上可以追溯到 Java 5)。这是一个更简单的答案 如果您可以使用 Java 9 或更高版本(因为
InputStream.readAllBytes()
是在 Java 9 中添加的):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt")
.readAllBytes(), UTF_8);
如果您担心文件名错误和/或关闭流,您可以稍微扩展一下:
String text = null;
InputStream stream = AppropriateClass.class.getResourceAsStream("foo.txt");
if (null != stream) {
text = stream.readAllBytes();
stream.close()
}
您可以使用以下Java代码
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
我自己也经常遇到这个问题。为了避免对小项目的依赖,我经常 当我不需要 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编辑你的文件,然后将其放入jar中,打开的计算机
文件可能将 CP-1251 作为其本机文件编码(例如);所以在
在这种情况下,您永远不知道目标编码,因此显式
编码信息至关重要。
此外,逐个字符读取文件的循环似乎效率低下,但它用于
BufferedReader,所以实际上相当快。这是使用 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);
}
}
如果您想从文件等项目资源中获取字符串
testcase/foo.json 在您项目的 src/main/resources 中,执行以下操作:String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
请注意,其他一些示例中缺少 getClassLoader() 方法。
使用 Apache commons 的 FileUtils。它有一个方法
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() : "";
}
}
}
无需第三方依赖项。至少从 Apache commons-io 2.5 开始,IOUtils.toString() 方法支持 URI 参数并返回位于类路径上的 jar 内的文件内容:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
通过一组静态导入,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;
}
}
List<String>
逐行:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
请参考这里来比较从文本文件中获取
BufferedReader
的3种方法(Files
与Guava的
Resources
与Guava的
String
)。这是我的方法,效果很好
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
}
}
如果您包含番石榴,那么您可以使用:
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");
我制作了这样的无依赖静态方法:
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 commons utils 来完成此类任务,并在测试时广泛使用这种确切的用例(从类路径读取文件),特别是从
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");