简体   繁体   中英

Loading resource files within a jar

What's the best way to load resources (Sounds, images, xml data), that also works from inside a distributed jar file?

I need to load some sounds, images, and xml data, for use in my program. Using

AudioInputStream ais = AudioSystem.getAudioInputStream(new File("~/src/com/example/package/name/assets/TestSound.wav"));

does not work in the jar, for obvious reasons, including the fact that src will not be in the jar.

Edit:

(A working) MWE: http://pastebin.com/CNq6zgPw

The ClassLoader class has two relevant methods:

  • getResource(path) delivers a URL for any resource on the classpath,
  • getResourceAsStream(path) delivers an input stream for the resource.

You can use these methods with overloads of the AudioSystem.getAudioInputStream(...) method to get an audio stream that reads a resource in your JAR file.


Note that if you call these methods on a ClassLoader object, that paths will be resolved in the namespaces of the JAR files on the classpath ... not the filesystem namespace of your development platform.

您可以从罐子中或罐子外部使用此代码加载任何资源:

InputStream is = this.getClass().getClassLoader().getResourceAsStream("~/src/package/name/assets/TestSound.wav");

This snippet of code worked for me:

Clip clip = null;
ClassLoader cl = this.getClass().getClassLoader();
AudioInputStream ais;
URL url = cl.getResource("com/example/project/assets/TestSound.wav");
System.out.println(url);
try {
    ais = AudioSystem.getAudioInputStream(url);
clip = AudioSystem.getClip();
clip.open(ais);
}
catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
}

The important thing is not adding the /src/ folder to the class path.

The critical change is changing cl.getResource("/com/example/project/assets/TestSound.wav") to cl.getResource("com/example/project/assets/TestSound.wav"); because /com/... indicates that the path is absolute, whereas com/... indicates that the path is relative.

For example,

System.out.println(new File("/Test.File").getAbsolutePath());
System.out.println(new File("Test.File").getAbsolutePath());

return

/Test.File
/Users/alphadelta/Documents/Workspace/TestProject/Test.File

respectively.

The first File created is created using "/Test.File" , which is absolute. The second is created using "Test.File" , which is relative to the project root in eclipse.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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