2014-09-05 125 views
4

我有以下目錄結構在我的Java項目:使用class.getResource()在.jar中加載文件?

enter image description here

該項目由Maven管理,並在包中的所有資源都投入到一個單一的.jar文件。
Utils.java我加載car.jpg,由於紋理文件在classpath中我用下面的方法來獲取有關文件句柄:

URL url = Utils.class.getResource("/textures/car.jpg"); 

我已經看到了關於很多的困惑在類路徑中獲取對文件的引用時使用哪種方法。
class.getResource()正確的使用方法?還是class.getResourceAsStream()提供任何好處?

+1

那麼如果你只是想'InputStream',我會使用'getResourceAsStream'。如果你正在使用一個很樂意使用'URL'的東西,那麼我們就是'getResource'。你的代碼不工作,或者你真的只是問這兩種方法中的哪一種? – 2014-09-05 16:55:38

+0

我沒有看到任何區別。這取決於你可以使用哪個返回值。例如'ImageIcon'將一個'URL'而不是'InputStream'作爲構造函數的參數。 – 2014-09-05 16:56:55

回答

1

兩者幾乎都是相同的,除了返回對象。 getResourceAsStream最終調用getResource,並返回顯示在下面的代碼片段從ClassLoader類的從URL對象打開InputStream

public InputStream getResourceAsStream(String name) { 
    URL url = getResource(name); 
    try { 
     return url != null ? url.openStream() : null; 
    } catch (IOException e) { 
     return null; 
    } 
} 
+1

雖然它通常是一個好主意,看源頭;你錯過了ClassLoader是一個抽象類,該方法不是最終的。由於各種原因,實現可能會覆蓋它(例如URLClassLoader)。 – Durandal 2014-09-05 17:55:02

0

遠離getResource()每當po ssible。在可以的地方使用getResourceAsStream()。

該規則背後的主要原因是資源的新URL(URL.toString())常常以完全意想不到的方式破壞,這取決於提供原始URL的類加載器。

與第一眼看上去不同的是,兩個相同字符串表示形式的網址並不是相同的,這取決於它們是如何構建的。這對標準化協議的URL不是問題。但它是由ClassLoader生成的URL;一個ClassLoader可以爲您提供這樣構造的URL:

new URL(URL context, String spec, URLStreamHandler handler) 

其中ClassLoader指定它自己的URLStreamHandler。處理器信息在這樣的URL被轉換爲字符串時丟失,並且無法恢復。然後你有一個看似有效的URL,這莫名其妙地不起作用。饒了你自己的麻煩:)