是否有一种方法将资源中的文本文件读入字符串?
我想这是一个普遍的需求,但我在谷歌上找不到任何实用工具。
是否有一种方法将资源中的文本文件读入字符串?
我想这是一个普遍的需求,但我在谷歌上找不到任何实用工具。
当前回答
对于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()));
其他回答
纯粹而简单,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用于其他任务,否则将这些库添加到项目中只是为了能够从文件中读取,这似乎有点过分。
我喜欢使用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 ...
}
我创建了这样一个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
}
我自己也经常遇到这个问题。为了避免对小项目的依赖,我经常 当我不需要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,非常快。
如果你有番石榴,那么你可以使用:
String fileContent = Files.asCharSource(new File(filename), Charset.forName("UTF-8")).read();
(其他解决方案提到了番石榴的其他方法,但已弃用)