資源(在類路徑上)

一個資源是一個路徑,如姓名,它駐留在 classpath 檔案資料等。資源的最常見用途是繫結應用程式影象,聲音和只讀資料(例如預設配置)。

可以使用 ClassLoader.getResourceClassLoader.getResourceAsStream 方法訪問資源。最常見的用例是將資源放在與讀取它們的類相同的包中; 在 Class.getResourceClass.getResourceAsStream 方法服務於這個常見的情況。

getResource 方法和 getResourceAsStream 方法之間的唯一區別是前者返回一個 URL,而後者開啟該 URL 並返回一個 InputStream。

ClassLoader 的方法接受類似路徑的資源名稱作為引數,並在 ClassLoader 的類路徑中搜尋與該名稱匹配的條目的每個位置。

  • 如果類路徑位置是 .jar 檔案,則具有指定名稱的 jar 條目將被視為匹配項。
  • 如果類路徑位置是目錄,則具有指定名稱的該目錄下的相對檔案將被視為匹配項。

資源名稱類似於相對 URL 的路徑部分。在*所有平臺上,*它使用正斜槓(/)作為目錄分隔符。它不能以斜線開頭。

類的相應方法是相似的,除了:

  • 資源名稱可以以斜槓開頭,在這種情況下,刪除初始斜槓,並將名稱的其餘部分傳遞給 ClassLoader 的相應方法。
  • 如果資源名稱不以斜槓開頭,則將其視為相對於正在呼叫其 getResource 或 getResourceAsStream 方法的類。實際的資源名稱變為 package / name ,其中 package 是類所屬的包的名稱,每個句點都用斜槓替換, name 是給該方法的原始引數。

例如:

package com.example;

public class ExampleApplication {
    public void readImage()
    throws IOException {

        URL imageURL = ExampleApplication.class.getResource("icon.png");

        // The above statement is identical to:
        // ClassLoader loader = ExampleApplication.class.getClassLoader();
        // URL imageURL = loader.getResource("com/example/icon.png");

        Image image = ImageIO.read(imageURL);
    }
}

資源應放在命名包中,而不是放在 .jar 檔案的根目錄中,原因與類放在包中的原因相同:防止多個供應商之間發生衝突。例如,如果多個 .jar 檔案位於類路徑中,並且其中多個檔案的根目錄中包含 config.properties 條目,則對 getResource 或 getResourceAsStream 方法的呼叫將從類路徑中首先列出的 .jar 返回 config.properties。。在類路徑順序不受應用程式直接控制的環境(例如 Java EE)中,這不是可預測的行為。

如果指定的資源不存在,則所有 getResource 和 getResourceAsStream 方法都返回 null。由於必須在構建時將資源新增到應用程式,因此在編寫程式碼時應該知道它們的位置; 在執行時找不到資源的失敗通常是程式設計師錯誤的結果。

資源是隻讀的。無法寫入資源。新手開發人員經常犯錯誤,因為在 IDE(如 Eclipse)中進行開發時,資源是一個單獨的物理檔案,因此在一般情況下將其視為單獨的物理檔案是安全的。但是,這是不正確的; 應用程式幾乎總是作為 .jar 或 .war 檔案等檔案進行分發,在這種情況下,資源不會是單獨的檔案而且不可寫。 (URL 類的 getFile 方法不是解決方法;儘管它的名稱,它只返回 URL 的路徑部分,這絕不保證是有效的檔名。)

沒有安全的方法在執行時列出資源。同樣,由於開發人員負責在構建時嚮應用程式新增資原始檔,因此開發人員應該已經知道他們的路徑。雖然有解決方法,但它們並不可靠,最終會失敗。