简体   繁体   English

使用class.getResource()在.jar中加载文件?

[英]Use class.getResource() to load file within .jar?

I have the following directory structure in my java project: 我的java项目中有以下目录结构:

在此输入图像描述

This project is managed by Maven , and when package all resources are put into a single .jar file. 该项目由Maven管理,当包将所有资源放入单个.jar文件中时。
Within Utils.java I'm loading car.jpg , and since the texture file is on the classpath I'm using the following method to get a handle on the file: Utils.java我正在加载car.jpg ,并且因为纹理文件在类路径上,所以我使用以下方法来获取文件的句柄:

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

I've seen a lot of confusion about which method to use when getting a reference to a file on the classpath. 我看到很多关于在类路径上获取对文件的引用时使用哪种方法的困惑。
Is class.getResource() the right method to use? class.getResource()是否使用正确的方法? Or does class.getResourceAsStream() offer any benefits? 或者class.getResourceAsStream()提供任何好处?

Both are pretty much the same except for the return object. 除返回对象外,两者几乎相同。 getResourceAsStream eventually calls getResource and returns an opened InputStream from the URL object as shown in the following snippet from the ClassLoader class: getResourceAsStream最终调用getResource并从URL对象返回一个打开的InputStream ,如以下ClassLoader类的片段所示:

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

http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getResourceAsStream-java.lang.String- http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getResourceAsStream-java.lang.String-

Given that the javadocs say exactly the same thing for both methods, I'd assume there are no benefits 鉴于javadocs对两种方法都说完全相同 ,我认为没有任何好处

Stay away from getResource() whenever possible. 尽可能远离getResource()。 Prefer getResourceAsStream() where you can. 首选getResourceAsStream()。

The main reasoning behind this rule is that new URL(URL.toString()) for resources often breaks in totally unexpected ways depending on the class loader which provided the original URL. 这条规则背后的主要原因是资源的新URL(URL.toString())经常以完全意想不到的方式中断,具体取决于提供原始URL的类加载器。

Unlike what it look like on first glance, two URL's of equal string representation are not treated the same , depending on how they were constructed. 与第一眼看上去不同的是,两个相等字符串表示的URL 不会被视为相同 ,具体取决于它们的构造方式。 That isn't a problem for URL's of standardized protocols. 对于标准化协议的URL,这不是问题。 But it is for URL's generated by a ClassLoader; 但它是由ClassLoader生成的URL; a ClassLoader can provide you an URL constructed this way: ClassLoader可以为您提供以这种方式构造的URL:

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

where the ClassLoader specifies its own URLStreamHandler. ClassLoader指定自己的URLStreamHandler。 The handler information is lost when such an URL is ever converted to String, and it can't be recovered. 当此类URL转换为String时,处理程序信息将丢失,并且无法恢复。 You then have a seemingly valid URL that inexplicably doesn't work. 然后,您有一个看似有效的URL,莫名其妙地无效。 Spare yourself the trouble :) 免除麻烦:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM