开发者

Open file; try filesystem first, then JARs

I'm trying to have my application load a resource (binary file) transparently:

If the file exists under the current directory, open it.

If not, try looking in the current JAR file if applicable.

If not, try looking in other JAR files. (This is optional and I don't mind explicitly specifying which JAR files.)

So far I know of File which opens a local file and ClassLoader which has getResource* for JAR contents.

Is there a class which combines the two? If not, how should I go about writing it myself? Should I write a ClassLoader which also checks the local filesystem? Using File? (I'm very unfamiliar with J开发者_如何学运维ava and don't even know what's a good type to return. InputStream?)

Thanks

P.S. By "file" I mean "path", e.g. "data/texture1.png".


Doing #1 and #3 is pretty easy. Doing #2 (just looking in the current JAR only) is much harder as it requires you figuring out what JAR you

If you wanted to check the filesystem first, otherwise load from classpath, it would be something like:

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);
  }
}

If you want to prefer loading from the same JAR file first, you will need to figure out where it is. Check out Determine which JAR file a class is from for more info on figuring out the JAR file you want to load the resource from.


A URLClassLoader should be able to load both and try the file path first if the file path is on the class path ahead of the jar.


Regarding your comments:

  • I know that relative jar URLs don't work. That's why the Spring guys came up with the Resource abstraction. Read about it here.
  • You might want to check the answers to this Question: Loading a file relative to the executing jar file. The problem is similar to yours.


Current jar file and current directory are not concepts in the JVM like they are when you're running a shell script. You would need to specify a directory to be used for loading the files that you're interested in, such as with a system property while executing the JVM:

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

Then retrieve this property:

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

Now when talking about JAR files, all JAR files specified explicitly on the classpath when you start the JVM are loaded by the ClassLoader. You can get the ClassLoader of a specific class by:

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

Note that any jar file loaded by the current class loader is searched.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜