簡體   English   中英

在Java中,為什么class.getResource(“ / path / to / res”); 將文件復制到系統時,無法在可運行的jar中工作?

[英]In Java, why does class.getResource(“/path/to/res”); not work in the runnable jar when copying files to the system?

我一直在從事一個項目,該項目要求用戶在首次運行時“安裝”該程序。 此安裝需要將所有資源從“ res”文件夾復制到用戶硬盤驅動器上的專用目錄。 我有下面的代碼塊運行良好,但是當我從eclipse中導出可運行的jar時,我收到了一個堆棧跟蹤,指示InputStream為null。 安裝循環將數組列表中每個文件的路徑傳遞給導出功能,這就是問題所在(使用InputStream)。 路徑已在Eclipse和可運行jar中正確傳遞,所以我懷疑這是問題所在。 我進行了研究,發現了類似的其他問題,但是建議的修復(使用類加載器等)均無效。 我不明白為什么我現在的方法可以在Eclipse中工作,但不能在jar中工作呢?

(還存在一個名為installFiles的File ArrayList)

private static String installFilesLocationOnDisk=System.getProperty("user.home")+"/Documents/[project name]/Resources/";

public static boolean tryInstall(){
    for(File file:installFiles){
//for each file, make the required directories for its extraction location
        new File(file.getParent()).mkdirs();
        try {
//export the file from the jar to the system 
            exportResource("/"+file.getPath().substring(installFilesLocationOnDisk.length()));
        } catch (Exception e) {
            return false;
        }
    }
    return true;
}

private static void exportResource(String resourceName) throws Exception {
    InputStream resourcesInputStream = null;
    OutputStream resourcesOutputStream = null;
    //the output location for exported files
    String outputLocation = new File(installFilesLocationOnDisk).getPath().replace('\\', '/');
    try {
        //This is where the issue arises when the jar is exported and ran.
        resourcesInputStream = InstallFiles.class.getResourceAsStream(resourceName);
        if(resourcesInputStream == null){
                throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
        }
        //Write the data from jar's resource to system file
        int readBytes;
        byte[] buffer = new byte[4096];
        resourcesOutputStream = new FileOutputStream(outputLocation + resourceName);
        while ((readBytes = resourcesInputStream.read(buffer)) > 0) {
            resourcesOutputStream.write(buffer, 0, readBytes);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
        System.exit(1);
    } finally {
        //Close streams
        resourcesInputStream.close();
        resourcesOutputStream.close();
    }
}

堆棧跟蹤:

java.lang.Exception: Cannot get resource "/textures\gameIcon.png" from Jar file.

感謝所有幫助! 謝謝

將您的JAR文件重命名為ZIP,將其解壓縮並檢查資源去向何處。

您可能會在Eclipse中使用Maven,這意味着使用Eclipse的功能導出Runnable JAR不會將資源正確放置在JAR中(如果您使用默認的Maven文件夾名稱,它們將最終位於JAR的文件夾資源下)約定)。

如果是這種情況,則應使用Maven的Assembly插件(或“ uber-JAR”的Shade插件)來創建可運行的JAR。

即使您沒有使用Maven,也應檢查資源是否正確放置在生成的JAR中。

PS也不要這樣做:

.getPath().replace('\\', '/');

而且永遠不要依賴特定的分隔符-使用java.io.File.separator來確定系統的文件分隔符。

堆棧跟蹤:

 java.lang.Exception: Cannot get resource "/textures\\gameIcon.png" from Jar file. 

資源錯誤時的名稱。 正如ClassLoader.getResource(String)的Javadoc描述的(而Class.getResourceAsStream(String)引用ClassLoader以獲得詳細信息):

資源的名稱是一個/分隔的路徑名,用於標識資源。

無論您是從文件系統還是從Jar文件中獲取資源,都應始終使用/作為分隔符。

使用\\有時可能會起作用,有時則不會:無法保證。 但這總是一個錯誤。

在您的情況下,解決方案是更改了調用exportResource

String path = file.getPath().substring(installFilesLocationOnDisk.length());
exportResource("/" + path.replace(File.pathSeparatorChar, '/'));

暫無
暫無

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

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