Java 使用 ClassLoader 加载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1119740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:00:34  来源:igfitidea点击:

Loading files with ClassLoader

javafileclassloader

提问by twolfe18

This problem has been bugging me for a while. I have to load a couple files in my java app, and the only way I got working so far looks like this:

这个问题困扰了我一段时间。我必须在我的 java 应用程序中加载几个文件,到目前为止我工作的唯一方法是这样的:

URL hsURL;
if(System.getProperty("os.name").toLowerCase().contains("windows")) {
    hsURL = new URL("file:/" + System.getProperty("user.dir") + "/helpsets/helpset.hs");
}
else {
    hsURL = new URL("file://" + System.getProperty("user.dir") + "/helpsets/helpset.hs");
}

But this is ugly and terrible. For a while I thought I had this working:

但这既丑陋又可怕。有一段时间我以为我有这个工作:

hsURL = ClassLoader.getSystemResource("helpsets/helpset.hs");

But that no longer works for some reason (I must have changed something and not noticed. It returns null.

但这由于某种原因不再有效(我一定是改变了一些东西而没有注意到。它返回空值。

Should I be using getResource() instead of getSystemResource() (if so, why is getSystemResource() static but not getResource())?

我应该使用 getResource() 而不是 getSystemResource() (如果是这样,为什么 getSystemResource() 是静态的而不是 getResource() )?

I am using eclipse and I have tried including the folder in the build path (classpath) and not including it, it doesn't seem to make a difference.

我正在使用 eclipse 并且我尝试在构建路径(类路径)中包含该文件夹而不包含它,它似乎没有什么区别。

采纳答案by Jon Skeet

getSystemResourceis static because it will use the systemclassloader, which is available statically. (ClassLoader.getSystemClassLoader)

getSystemResource是静态的,因为它将使用静态可用的系统类加载器。( ClassLoader.getSystemClassLoader)

If your resource is available in the classpath, I would suggest using ClassLoader.getResource()or Class.getResourcefrom an appropriate class, e.g.

如果您的资源在类路径中可用,我建议使用ClassLoader.getResource()Class.getResource来自适当的类,例如

Foo.class.getResource("/helpsets/helpset.hs");

(ClassLoader.getResourceis "absolute"; Class.getResourceis relative to the package of the class unless you prefix it with a '/'.)

ClassLoader.getResource是“绝对的”;Class.getResource是相对于类的包的,除非你在它前面加上一个“/”。)

If this doesn't work, please post how your app is configured in terms of the classpath, and where your file is.

如果这不起作用,请发布您的应用程序是如何根据类路径配置的,以及您的文件在哪里。

EDIT: I usually find the URL less useful than an InputStream, so I use getResourceAsStreaminstead of getResource. YMMV

编辑:我通常发现 URL 不如 有用InputStream,所以我使用getResourceAsStream代替getResource。青年会

回答by kdgregory

You've mentioned several different things here, so let's sort them out.

你在这里提到了几个不同的事情,所以让我们把它们整理一下。

1) Creating a "file:" URL based on "user.dir"

1) 基于“user.dir”创建一个“file:” URL

The "user.dir" property refers to the current working directory -- wherever the user might have been when s/he started the app. Chances are good that files written here will disappear between two runs (because the user might run from a different directory).

“user.dir”属性指的是当前工作目录——用户启动应用程序时可能所在的位置。在两次运行之间,这里写的文件很可能会消失(因为用户可能从不同的目录运行)。

The "user.home" property refers to the user's home directory -- which should remain the same between runs.

“user.home”属性指的是用户的主目录——在两次运行之间应该保持不变。

In either case, use a File object to open files, don't muck around with creating a "file:" URL. You get no benefit, and as you can see, you have to write messy code to access it.

在任何一种情况下,使用 File 对象打开文件,不要乱创建“file:” URL。你没有得到任何好处,正如你所看到的,你必须编写凌乱的代码才能访问它。

2) Retrieving a resource via the classloader

2) 通过类加载器获取资源

This is meant to retrieve files that are packaged with your application -- read-only files. As you have seen, there are multiple variants. I prefer using the following, because I assume that a class will want to load a file that's packaged with it.

这是为了检索与您的应用程序打包在一起的文件——只读文件。如您所见,有多种变体。我更喜欢使用以下内容,因为我假设一个类将要加载一个与它打包在一起的文件。

InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName);