Answers:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
正在使用的实现,Resource.class.getClassLoader
但是在Web应用程序中,这可能不是“您的”类加载器,因此建议(例如[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();
伙计们,除非您确实需要,否则请不要使用第三方的东西。JDK中已经有很多功能。
CartApplication.class.getResourceAsStream
为CartApplication.class.getClassLoader().getResourceAsStream
在当前jar中加载资源。.如srm / test / resources
对于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来执行其他任务,否则将这些库添加到项目中只是为了能够从文件中读取似乎有点过多。
我了解到纯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
。
番石榴有一个“ toString”方法,用于将文件读入字符串:
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 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
我自己经常遇到这个问题。为了避免依赖小型项目,我经常在不需要common 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作为其本机文件编码(例如) ; 因此在这种情况下,您永远不会知道目标编码,因此显式编码信息至关重要。同样,通过char读取文件char的循环看起来效率很低,但是它用在BufferedReader上,因此实际上非常快。
您可以使用以下代码形式的Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
使用Apache Commons的FileUtils。它有一个方法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;
}
}
Files.readLines()
如果您想List<String>
逐行返回值,番石榴还具有:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
请参考此处以比较从文本文件中获取3种方法(BufferedReader
与Guava的Files
对比与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方法,并且我想将以这种方式进行更改。
这是使用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);
}
}
我做了这样的无依赖静态方法:
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用于此类内容,并在测试时广泛使用此确切的用例(从类路径读取文件),尤其是/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 ...
}
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");