簡體   English   中英

為什么jar內的資源使用java.lang.ClassLoader.getResource

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

使用 Java 8、Tomcat 8+。

我遇到過這樣的問題 - 我正在嘗試讀取 lib 中 jar 內的 txt 資源。 我使用了以下代碼:

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")

雖然它在我的 Intellij IDEA 上運行良好,但在 Tomcat 服務器上部署后出現了這樣的異常:

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' 確實不存在

在那之后,我在 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()

好的,我對工作解決方案感到滿意。 但我在任何地方都找不到任何明確的解釋:為什么 getResourceAsStream 有效,同時“文件”方法不適用於 JAR 內的資源? 我很好奇,因為superService.getClass().getClassLoader().getResource("com/domain/example/sorry/confidential/little_text.txt")返回的不是 null,但是構造的文件有canRead() == falseisExist() == false

File、FileInputStream、FileUtils 等旨在訪問文件系統,從文件系統的角度來看,嵌入在 JAR 中的“文件”實際上並不是文件。 因此,您只能通過實際用於從存檔內部讀取的工具訪問這些嵌入式文件(基本上,JAR 只是一個奇特的 ZIP)。

順便說一句,您的 Java 中的文件 object 不為空並不意味着該文件實際存在。 你可以這樣做:

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

file將是非空的(但isReadable()isExist()應該是假的)。 這與您為資源獲得的行為相同。

它可能在 IDE 中有效,因為該文件確實作為非存檔文件存在於您的工作區中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM