There may be a lot of beginners who may be confused like this (I have used it before): You have called some resource files, movies, music, etc in your code, it can be displayed or played normally in the debugging environment or when it is run independently. Once packaged into a jar file, these items will be retained, unless you put this jar in the directory before packaging, but it is usually released separately. Here is a solution to this type of problem.
Getresource and getresourceasstream
The root cause of the problem is the so-called class path. If you don't believe it, you can add your jar file to the classpath in the system environment variable. Now you can see your picture! However, if you release a jar file separately, it is impossible to expect the user to modify the classpath for your jar every time. Is there any way to fix it once and for all? We need to start with class loading. First, what should I do if I need to use a third-party library when developing Web applications such as JSP? The general practice is to put these libraries (can be class, can also be jar) All put under the WEB-INF/lib/directory, why is this system recognized? Because Web containers (such as Tomcat) have their own organizational structure when loading classes (refer to the Tomcat manual http: // jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html ). In particular, jar is also an accessible medium for the Class Loader. classloader provides two methods for obtaining resources from the loaded class path:
Public URL getresource (string name );
Public inputstream getresourceasstream (string name );
Here name is the class path of the resource, which is relative to the location under the "/" root path. Getresource obtains a URL object to locate the resource, while getresourceasstream obtains the reference of the resource input stream to ensure that the program can extract data from the correct position.
Actually, this is not the two methods of classloader, but the getresource and getresourceasstream methods of the class, because the class object can be obtained from your class (such as yourclass. class or yourclass. getclass (), while classloader needs to call yourclass again. the getclassloader () method, but according to the JDK documentation, the two methods of the class object are actually "delegate" (delegate) to the classloader that loads it, therefore, you only need to use the two methods of the Class Object.
In the reference documents, I wrote an article about how to load resources from jar.
Example of an application
The following is a piece of code used in msnhistorycombiner, a small tool I wrote. It can load image and text information from jar. For example, if your jars root directory contains an IMG directory with some images, such as img1.jpg, you can call
Utilities. getimagefromjar ("/img/img1.jpg", yourclass. Class );
It must be "/img/img1.jpg" instead of "img/img1.jpg ". Reading text resources from jar is similar to calling gettextfromjar.
It should be noted that this piece of code is not my original one. It is modified from another piece of code, but the source of the original code is forgotten. Here, I would like to express my gratitude and apologies to the original author.
Import java. AWT. image;
Import java. AWT. toolkit;
Import java. Io .*;
Public class resoursereader {
Public resoursereader (){
}
Public static image getimagefromjar (string S, class class1 ){
Image image = NULL;
Inputstream = class1.getresourceasstream (s );
If (inputstream! = NULL ){
Bytearrayoutputstream = new bytearrayoutputstream ();
Try {
Byte abyte0 [] = new byte [1024];
For (INT I = 0; (I = inputstream. Read (abyte0)> = 0 ;){
Bytearrayoutputstream. Write (abyte0, 0, I );
}
Image = toolkit. getdefatooltoolkit (). createimage (bytearrayoutputstream. tobytearray ());
}
Catch (ioexception ){
Ioexception. printstacktrace ();
}
}
Return image;
}
Public static string gettextfromjar (string S, class class1 ){
String S1 = "";
Inputstream = class1.getresourceasstream (s );
If (inputstream! = NULL ){
Bufferedreader = new bufferedreader (New inputstreamreader (inputstream ));
String S2;
Try {
While (s2 = bufferedreader. Readline ())! = NULL ){
S1 = S1 + S2 + "/N ";
}
}
Catch (ioexception ){
Ioexception. printstacktrace ();
}
}
Return S1;
}
}
Read GIF files from jar
In Java program release, many people choose to publish in the binary jar format. How can I read resources in jar?
The following methods of classloader are used for implementation:
Public URL getresource (string name );
Public inputstream getresourceasstream (string name)
Public static inputstream getsystemresourceasstream (string name)
Public static URL getsystemresource (string name)
The last two methods can be seen as static methods. Both of these methods can read image resources from jar files. However, during the attempt, I found that, there are some differences.
String gifname is the relative path of the GIF file in jar.
(1) Two static methods are used.
Bufferedimage image = ImageIO. Read (classloader. getsystemresourceasstream (gifname ));
Or
Image image = toolkit. getdefatooltoolkit (). getimage (classloader. getsystemresource (gifname ));
These two methods can successfully read GIF files, but the GIF animation is displayed static.
(2) Use the other two methods
Image image = toolkit. getdefatooltoolkit (). getimage (this. getclass. getclassloader (). getresource (gifname ));
In this way, the animation can be displayed normally.