如何从资源文件夹加载文件?

cod*_*ons 211 java file maven

我的项目有以下结构:

/src/main/java/
/src/main/resources/
/src/test/java/
/src/test/resources/
Run Code Online (Sandbox Code Playgroud)

我有一个文件,/src/test/resources/test.csv我想从单元测试加载文件/src/test/java/MyTest.java

我有这个代码不起作用.它抱怨"没有这样的文件或目录".

BufferedReader br = new BufferedReader (new FileReader(test.csv))
Run Code Online (Sandbox Code Playgroud)

我也尝试过这个

InputStream is = (InputStream) MyTest.class.getResourcesAsStream(test.csv))
Run Code Online (Sandbox Code Playgroud)

这也行不通.它回来了null.我正在使用Maven来构建我的项目.

Pau*_*gas 209

尝试下一个:

ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream("test.csv");
Run Code Online (Sandbox Code Playgroud)

如果上述方法不起作用,则会在以下类中添加各种项目:1(此处为代码).2ClassLoaderUtil

以下是如何使用该类的一些示例:

src\main\java\com\company\test\YourCallingClass.java
src\main\java\com\opensymphony\xwork2\util\ClassLoaderUtil.java
src\main\resources\test.csv
// java.net.URL
URL url = ClassLoaderUtil.getResource("test.csv", YourCallingClass.class);
Path path = Paths.get(url.toURI());
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
Run Code Online (Sandbox Code Playgroud)
// java.io.InputStream
InputStream inputStream = ClassLoaderUtil.getResourceAsStream("test.csv", YourCallingClass.class);
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
for (String line; (line = reader.readLine()) != null;) {
    // Process line
}
Run Code Online (Sandbox Code Playgroud)

笔记

  1. The Wayback Machine中看到它.
  2. 也在GitHub.

  • 谢谢你的回答,请你解释为什么我们应该使用这个非常具体的装载机而不是班级的装载机? (13认同)
  • @ycomp因为getResource返回一个URL而不是一个文件.java.net.URL**的getFile方法不会将URL转换为文件; 它只返回URL的路径和查询部分.您甚至不应该尝试将其转换为文件; 只需调用openStream并从中读取. (4认同)

van*_*nza 52

尝试:

InputStream is = MyTest.class.getResourceAsStream("/test.csv");
Run Code Online (Sandbox Code Playgroud)

getResourceAsStream()默认情况下,IIRC 是相对于类的包.

  • “ /”是关键。 (5认同)
  • 对于那些寻求理智的人,这篇文章将带您一路将资源作为“字符串” /sf/answers/2481220661/ (3认同)

Dat*_*eek 33

以下是使用番石榴的一种快速解决方案:

import com.google.common.base.Charsets;
import com.google.common.io.Resources;

public String readResource(final String fileName, Charset charset) throws IOException {
        return Resources.toString(Resources.getResource(fileName), charset);
}
Run Code Online (Sandbox Code Playgroud)

用法:

String fixture = this.readResource("filename.txt", Charsets.UTF_8)
Run Code Online (Sandbox Code Playgroud)

  • 文档说关于“getResource”方法:“getResource(java.lang.String)”是在标有@Beta的不稳定类“com.google.common.io.Resources”中声明的。人们真的应该使用不稳定类中的方法吗? (2认同)

srs*_*jid 23

尝试在Spring项目上使用Flowing代码

ClassPathResource resource = new ClassPathResource("fileName");
InputStream inputStream = resource.getInputStream();
Run Code Online (Sandbox Code Playgroud)

或者在非春季项目上

 ClassLoader classLoader = getClass().getClassLoader();
 File file = new File(classLoader.getResource("fileName").getFile());
 InputStream inputStream = new FileInputStream(file);
Run Code Online (Sandbox Code Playgroud)

  • 不应该关闭InputStream吗? (3认同)
  • 这个答案适用于 war 文件,不适用于 jar 文件。 (3认同)

fua*_*uat 14

非弹簧项目:

String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath();

Stream<String> lines = Files.lines(Paths.get(filePath));
Run Code Online (Sandbox Code Playgroud)

或者

String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath();

InputStream in = new FileInputStream(filePath);
Run Code Online (Sandbox Code Playgroud)

对于spring项目,也可以使用一行代码获取resources文件夹下的任意文件:

File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "any.json");

String content = new String(Files.readAllBytes(file.toPath()));
Run Code Online (Sandbox Code Playgroud)


小智 6

对于1.7 之后的Java

 List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("test.csv").toURI()));
Run Code Online (Sandbox Code Playgroud)


小智 5

ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("test.csv");
Run Code Online (Sandbox Code Playgroud)

如果使用上下文ClassLoader查找资源,那么肯定会降低应用程序性能。

  • @Marvo:程序员必须始终关注质量,功能和易于维护,性能迫在眉睫。 (5认同)
  • 程序员应始终关注性能。虽然一定要避免过早的优化,但是知道采取更有效的方法总是好的。这就像知道LinkedList和ArrayList之间的区别以及何时使用一个或另一个有关。 (4认同)

Ari*_*afa 5

现在我要说明从maven创建的资源目录中读取字体的源代码,

SCR /主/资源/ calibril.ttf

在此输入图像描述

Font getCalibriLightFont(int fontSize){
    Font font = null;
    try{
        URL fontURL = OneMethod.class.getResource("/calibril.ttf");
        InputStream fontStream = fontURL.openStream();
        font = new Font(Font.createFont(Font.TRUETYPE_FONT, fontStream).getFamily(), Font.PLAIN, fontSize);
        fontStream.close();
    }catch(IOException | FontFormatException ief){
        font = new Font("Arial", Font.PLAIN, fontSize);
        ief.printStackTrace();
    }   
    return font;
}
Run Code Online (Sandbox Code Playgroud)

它对我有用,并希望整个源代码也能帮到你,享受!


Yan*_*ski 5

我遇到了同样的问题

类加载器未找到该文件,这意味着它未打包到工件 (jar) 中。您需要构建项目。例如,使用 maven:

mvn clean install
Run Code Online (Sandbox Code Playgroud)

因此,您添加到资源文件夹中的文件将进入 maven 构建并可供应用程序使用。

我想保留我的答案:它没有解释如何读取文件(其他答案确实解释了这一点),它回答了为什么 InputStreamresourcenull。类似的答案是here

  • 谢谢,让我免于失去理智! (2认同)