簡體   English   中英

如何正確引用資源文件以進行JAR和調試?

[英]How to reference a resource file correctly for JAR and Debugging?

在使用Maven項目和Jar文件時,我有一個令人討厭的問題引用資源...

我將所有資源都放在專用文件夾/ src / main / resources中,這是Eclipse中構建路徑的一部分。 使用引用文件

getClass().getResource("/filename.txt")

這在Eclipse中運行良好但在Jar文件中失敗 - 資源位於jar根目錄正下方的文件夾中...

有沒有人知道在JAR和Eclipse中的(!)引用文件的“最佳實踐”?

編輯:問題是,雖然資源實際上位於頂級文件夾“資源”中的JAR中,但上述方法無法找到文件...

我遇到了類似的問題。 經過一整天的嘗試每一個組合和調試后,我嘗試了getClass()。getResourceAsStream(“resources / filename.txt”)並最終使其工作。 沒有其他任何幫助。

Maven資源文件夾的內容被復制到目標/類,並從那里復制到生成的Jar文件的根目錄。 這是預期的行為。

我不明白的是你的場景中存在的問題。 通過getClass().getResource("/filename.txt")引用資源getClass().getResource("/filename.txt")從類路徑的根開始,無論是(或其元素)是target/classes還是JAR的根。 我看到的唯一可能的錯誤是你使用了錯誤的ClassLoader

確保使用該資源的類與資源位於同一工件(JAR)中,並執行ThatClass.class.getResource("/path/with/slash")ThatClass.class.getClassLoader().getResource("path/without/slash")

但除此之外:如果它不起作用,你可能在構建過程中的某個地方做錯了什么。 你能驗證資源是否在JAR中?

打包JAR后,您的資源文件不再是文件,而是流,因此getResource不起作用!

使用getResourceAsStream

要獲取“文件”內容,請使用https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html

static public String getFile(String fileName)
{
        //Get file from resources folder
        ClassLoader classLoader = (new A_CLASS()).getClass().getClassLoader();

        InputStream stream = classLoader.getResourceAsStream(fileName);

        try
        {
            if (stream == null)
            {
                throw new Exception("Cannot find file " + fileName);
            }

            return IOUtils.toString(stream);
        }
        catch (Exception e) {
            e.printStackTrace();

            System.exit(1);
        }

        return null;
}

也許這種方法可以幫助某些情況。

public static File getResourceFile(String relativePath)
{
    File file = null;
    URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
    String codeLocation = location.toString();
    try{
        if (codeLocation.endsWith(".jar"){
            //Call from jar
            Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
            file = path.toFile();
        }else{
            //Call from IDE
            file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
        }
    }catch(URISyntaxException ex){
        ex.printStackTrace();
    }
    return file;
}

如果你在jar文件中添加資源目錄(因此它位於jar中的/ resources文件夾下,如果/ src / main位於eclipse中的構建路徑中,那么你應該能夠將你的文件引用為:

getClass().getResource("/resources/filename.txt");  

哪個應該適用於兩種環境。

問題是在IDE中getClass()。getResource(“Path”); 訪問文件時,字符串不是CASE SENSITIVE,而是從jar運行時。 檢查與文件相比的目錄上的大小寫。 它確實有效。 此外,如果您嘗試新的File(getClass()。getResource(“Path”);該文件將無法在IDE外部讀取。

只需將文件復制到臨時目錄即可。

String tempDir = System.getProperty("java.io.tmpdir");
File file = new File(tempDir.getAbsolutePath(), "filename.txt");
if (!file.exists()) {
     InputStream is = (getClass().getResourceAsStream("/filename.txt"));
     Files.copy(is, file.getAbsoluteFile().toPath());
}

暫無
暫無

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

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