简体   繁体   English

为什么jar内的资源使用java.lang.ClassLoader.getResource

[英]Why to use java.lang.ClassLoader.getResource for resource within jar

Using Java 8, Tomcat 8+.使用 Java 8、Tomcat 8+。

I have faced with such problem - I'm trying to read txt resource within jar in lib.我遇到过这样的问题 - 我正在尝试读取 lib 中 jar 内的 txt 资源。 I have used the following code:我使用了以下代码:

import java.io.File;
import org.apache.commons.io.FileUtils;

// ....    
// code within some class method
File file = new File(superService.getClass().getClassLoader()
                    .getResource("com/domain/example/sorry/confidential/little_text.txt")
                    .getFile())
return FileUtils.readFileToString(file, "UTF-8")

Though it worked well running from my Intellij IDEA, I got such kind of exception after deploy on Tomcat server:虽然它在我的 Intellij IDEA 上运行良好,但在 Tomcat 服务器上部署后出现了这样的异常:

java.io.FileNotFoundException: File 'file:/usr/local/tomcat/webapps/prod-lims/WEB-INF/lib/abc-1.2-SNAPSHOT.jar.com/domain/example/sorry/confidential/little_text.txt' does not exist java.io.FileNotFoundException: 文件 'file:/usr/local/tomcat/webapps/prod-lims/WEB-INF/lib/abc-1.2-SNAPSHOT.jar.com/domain/example/sorry/confidential/little_text.txt' 确实不存在

And after that I found a lot of answers in SO and other sites that I need to use ClassLoader.getResourceAsStream() or Class.getResourceAsStream() methods for resources within JAR. Of course, I tried to re-design my code in old-style way and - voila: - it works now:在那之后,我在 SO 和其他网站上找到了很多答案,我需要使用 ClassLoader.getResourceAsStream() 或 Class.getResourceAsStream() 方法来获取 JAR 内的资源。当然,我尝试重新设计我的代码 -样式方式和 - 瞧: - 现在可以使用了:

import java.io.BufferedReader;
import java.io.InputStreamReader;

// ....    
// code within some class method
InputStream inputStream = superService.getClass().getClassLoader()
               .getResourceAsStream("com/domain/example/sorry/confidential/little_text.txt")


StringBuilder resultStringBuilder = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))
    try {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
        }
        } catch(Exception e) {
        //just a formal catch - don't mind for now
    }

return resultStringBuilder.toString()

Ok, I'm happy with the working solution.好的,我对工作解决方案感到满意。 But I can not find any clear explanation anywhere: why getResourceAsStream works and at the same time 'File' approach doesn't work for resources within JAR?但我在任何地方都找不到任何明确的解释:为什么 getResourceAsStream 有效,同时“文件”方法不适用于 JAR 内的资源? I'm curious because superService.getClass().getClassLoader().getResource("com/domain/example/sorry/confidential/little_text.txt") returns not null, but the constructed file has canRead() == false and isExist() == false .我很好奇,因为superService.getClass().getClassLoader().getResource("com/domain/example/sorry/confidential/little_text.txt")返回的不是 null,但是构造的文件有canRead() == falseisExist() == false

File, FileInputStream, FileUtils et cetera are intended to access the file system, and a "file" that is embedded inside a JAR is not actually a file from the file system's point of view. File、FileInputStream、FileUtils 等旨在访问文件系统,从文件系统的角度来看,嵌入在 JAR 中的“文件”实际上并不是文件。 Thus, you can only access those embedded files through tools that are actually intended to read from inside an archive (a JAR is just a fancy ZIP, basically).因此,您只能通过实际用于从存档内部读取的工具访问这些嵌入式文件(基本上,JAR 只是一个奇特的 ZIP)。

Incidentally, the fact that your File object in Java is non-null does not mean the file actually exists.顺便说一句,您的 Java 中的文件 object 不为空并不意味着该文件实际存在。 You could do this just fine:你可以这样做:

File file = new File("I:\\do\\not.exist");

and file would be non-null (but isReadable() and isExist() should be false).file将是非空的(但isReadable()isExist()应该是假的)。 Which is the same behaviour you get for your resource.这与您为资源获得的行为相同。

It likely works in the IDE because the file does actually exist as a non-archived file in your workspace.它可能在 IDE 中有效,因为该文件确实作为非存档文件存在于您的工作区中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM