2010-09-29 38 views
1

我试图让我的应用程序透明地加载资源(二进制文件):打开文件;先尝试文件系统,然后JAR

如果该文件存在于当前目录下,请将其打开。
如果没有,请尝试查看当前的JAR文件(如果适用)。
如果不是,请尝试查看其他JAR文件。 (这是可选的,我不介意明确指定该JAR文件)。

到目前为止,我所知道的File打开一个本地文件和ClassLoader具有getResource*为JAR内容。

是否有一个结合了两者的课程?如果不是,我该怎么去写自己的?我应该写一个ClassLoader这也检查本地文件系统?使用File? (我很熟悉的Java,甚至不知道什么是一个很好的类型返回。InputStream?)

感谢

附: “文件”的意思是“路径”,例如“数据/ texture1.png”。

回答

5

做#1和#3很容易。这样做#2(只是希望只在当前JAR)是因为它需要你搞清楚什么JAR你

如果你想首先检查文件系统,否则从classpath中加载,这将是像更难:

public java.io.InputStream loadByName(String name) { 
    java.io.File f = new java.io.File(name); 
    if (f.isFile()) { 
    return new FileInputStream(f); 
    } else { 
    return getClass().getResource(name); 
    } 
} 

如果您希望首先从同一个JAR文件加载,则需要确定它在哪里。查看Determine which JAR file a class is from以获取更多关于计算要从中加载资源的JAR文件的信息。

+0

我害怕我可能需要这样的功能:( - 感谢指向另一个问题btw的指针。 – aib 2010-09-29 17:09:57

3

A URLClassLoader应该能够加载并且如果文件路径位于jar之前的类路径上,则首先尝试文件路径。


关于你的评论:

+0

啊,太好了。这可能正是我要找的。 – aib 2010-09-29 17:09:27

+0

事实的确如此!但有一个问题:为什么我不能使用'new URL(“file:foo.jar!/ data”)?我似乎无法使用'!/'! – aib 2010-09-30 01:21:28

+0

Err和另外一件事,它似乎更喜欢JAR中的文件,而不管我给出路径的顺序。 – aib 2010-09-30 01:30:35

1

当前的jar文件和当前目录不像JVM中的概念,就像它们在运行shell脚本时一样。您将需要指定一个目录将用于加载您感兴趣的文件,如用在执行JVM的系统属性:

java -Ddirectory.to.scan=/home/aib 

然后检索该属性:

String dir = System.getProperty("directory.to.scan"); 

现在谈到JAR文件时,ClassLoader会加载启动JVM时在类路径上显式指定的所有JAR文件。

InputStream is = <Your class>.class.getClassLoader().getResourceAsStream("binary file"); 

需要注意的是当前类加载器加载任何jar文件中搜索:您可以通过获取特定类的类加载器。