2014-09-05 88 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,这莫名其妙地不起作用。饶了你自己的麻烦:)