Java 使用类加载器加载文件

Java 使用类加载器加载文件,java,file,classloader,Java,File,Classloader,这个问题困扰了我一段时间。我必须在我的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 UR

这个问题困扰了我一段时间。我必须在我的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");
}
但这是丑陋和可怕的。有一段时间,我认为我有这个工作:

hsURL = ClassLoader.getSystemResource("helpsets/helpset.hs");
但由于某种原因,它不再有效(我必须更改了某些内容,但没有注意到。它返回null)

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


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

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

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

Foo.class.getResource("/helpsets/helpset.hs");
ClassLoader.getResource
是“绝对的”;
Class.getResource
是相对于类的包的,除非您在它前面加上“/”前缀。)

如果这不起作用,请发布应用程序在类路径方面的配置,以及文件的位置


编辑:我通常发现URL不如
InputStream
有用,所以我使用
getresourceastream
而不是
getResource
。YMMV

您在这里提到了一些不同的东西,让我们来整理一下

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

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

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

在任何一种情况下,都可以使用文件对象打开文件,不要随意创建“文件:”URL。您得不到任何好处,正如您所看到的,您必须编写混乱的代码才能访问它

2) 通过类加载器检索资源

这意味着检索与应用程序一起打包的文件——只读文件。如您所见,有多种变体。我更喜欢使用下面的方法,因为我假设一个类将要加载一个与它一起打包的文件

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

如果您只对内容感兴趣,那么最好在ClassLoaderwell上使用getResourceAsStream(),因为我还没有实现这一点。我正试图加载一个文件,该文件与我从中加载它的类位于不同的包中,因此我需要某种绝对引用。@twolfe18:是的,因此请使用“/helpset/helpset.hs”,如答案所示@Rich:是的,将进行编辑以提及这一点。在项目文件夹中有源程序包和帮助集程序包。源程序包的设置方式如下:src/foo/bar/my_classe除非helpsets程序包被设置为包含在输出中(例如,通过将其设置为源路径),否则它将不会出现在bin目录中(或放置输出的任何位置),因此您将无法获取它。