Java tip 49: how to extract Java resources from jar and ZIP files
Are you getting started with the JAR file? This new class can help you solve the problem!
Author:John D. Mitchell and Arthur Choi
Summary
Packaging a class of Java resources in a Java archive (jar) file is an excellent way to shorten the download time, enhance security, and enhance manageability. This tip describes how to easily extract resources from jar files for your own use.
Most Java programmers are very clear about the advantages of using jar files to package various resources (such as. class files, sounds, and images) that constitute the Java solution. (If you are not familiar with jar files, refer to the reference resources section below .) A frequently asked question when using jar files is: "How to extract images from jar files ?" This article will answer this question and provide a class, which makes it very easy to extract any resources from the jar file!
Load GIF images
Suppose we have a jar file that contains a set of. GIF images to be used by our application. The following describes how to use jarresources to access image files in jar files:
JarResources jar = new JarResources ("Images.jar");
Image logo =
Toolkit.getDefaultToolkit().createImage (jar.getResource ("logo.gif");
This Code shows that we can createJarResources
Object, and initialize it as a jar file containing the resources we want to use --Images.jar
. Then we useJarResources
OfgetResource()
Methods: provide raw data from the logo.gif file tocreateImage()
Method.
Description
Jarresource is a simple example of how to use various functions provided by Java 1.1 to process jar and ZIP files.
A brief description of naming. The archive support in Java is actually based on the popular ZIP Archive format (see "Java tip 21: Use archive files to speed up applet loading "). Therefore, when Java support for file processing is initially implemented, all class files and such things are not included in the java.util.zip package"Zip
. However, when you switch to Java 1.1, the function has changed, and the file name is more java-specific. Therefore, the files that we call jar files are basically ZIP files.
Work Mode
JarResources
Important data fields of the class are used to track and store the content of the specified JAR file:
public final class JarResources {
public boolean debugOn=false;
private Hashtable htSizes=new Hashtable();
private Hashtable htJarContents=new Hashtable();
private String jarFileName;
In this way, set the name of the JAR file for the class instantiation, and then goinit()
Method to complete all the actual work.
public JarResources(String jarFileName) {
this.jarFileName=jarFileName;
init();
}
Now,init()
Method: load the entire content of the specified JAR file to a hashtable (accessed by resource name.
This is a very useful method. Next we will analyze it further.ZipFile
Class provides us with basic access to the JAR/ZIP file header information. This is similar to the directory information in the file system. Below we listZipFile
All entries in, and add the size of each resource in the fileHtsizesHashtable:
private void init() {
try {
ZipFile zf=new ZipFile(jarFileName);
Enumeration e=zf.entries();
while (e.hasMoreElements()) {
ZipEntry ze=(ZipEntry)e.nextElement();
if (debugOn) {
System.out.println(dumpZipEntry(ze));
}
htSizes.put(ze.getName(),new Integer((int)ze.getSize()));
}
zf.close();
Next, we useZipInputStream
Class access file.ZipInputStream
Class completes all magic, allowing us to read each resource in the file separately. We read the exact number of bytes that constitute each resource from the archive and store it inHtjarcontentsIn hashtable, you can access the data using the Resource Name:
Fileinputstream FCM = new fileinputstream (jarfilename );
Bufferedinputstream Bis = new bufferedinputstream (FCM );
Zipinputstream zis = new zipinputstream (bis );
Zipentry ze = NULL;
While (ze = Zis. getnextentry ())! = NULL ){
If (ze. isdirectory ()){
Continue;
}
If (debugon ){
System. Out. println (
"Ze. getname () =" + Ze. getname () + "," + "getsize () =" + Ze. getsize ()
);
}
Int size = (INT) Ze. getsize ();
//-1 indicates that the size is unknown.
If (size =-1 ){
Size = (integer) htsizes. Get (ze. getname (). intvalue ();
}
Byte [] B = new byte [(INT) size];
Int RB = 0;
Int chunk = 0;
While (INT) size-Rb)> 0 ){
Chunk = Zis. Read (B, Rb, (INT) size-Rb );
If (chunk =-1 ){
Break;
}
RB + = chunk;
}
// Add it to the internal resource hashtable
Htjarcontents. Put (ze. getname (), B );
If (debugon ){
System. Out. println (
Ze. getname () + "RB =" + RB +
", Size =" + size +
", Csize =" + Ze. getcompressedsize ()
);
}
}
} Catch (nullpointerexception e ){
System. Out. println ("done .");
} Catch (filenotfoundexception e ){
E. printstacktrace ();
} Catch (ioexception e ){
E. printstacktrace ();
}
}
Note that the name used to identify each resource is the qualified path name of the resource in the file, for example,NoClass name in the package-that is, in the java.util.zip packageZipEntry
Class will be named "Java/util/zip/zipentry" instead of "java.util.zip. zipentry ".
The last important part of the code is a simple test driver. The test driver is a simple application that receives the JAR/ZIP file name and Resource Name. It tries to find the resource file in the file and then reports the message of success or failure:
public static void main(String[] args) throws IOException {
if (args.length!=2) {
System.err.println(
"usage: java JarResources "
);
System.exit(1);
}
JarResources jr=new JarResources(args[0]);
byte[] buff=jr.getResource(args[1]);
if (buff==null) {
System.out.println("Could not find "+args[1]+".");
} else {
System.out.println("Found "+args[1]+ " (length="+buff.length+").");
}
}
} // The jarresources class ends.
You have learned about this class. An easy-to-use class that hides all the thorny issues of using resources packaged in jar files.
Exercise
Now you have some knowledge about extracting resources from archive files. The following describes how to modify and expand resources.JarResources
Class description:
- Delayed loading is not required because all content is loaded at one time during construction. For large jar files, there may not be enough memory to load all files during the construction.
- Not only
getResource()
For such a general read method, we can also provide resource-specific read methods-for example, to returnImage
ObjectgetImage()
Method, used to return JavaClass
ObjectgetClass()
Method (with the assistance of a custom Class Loader. If the JAR file is small enough, we can compile their extension names (.gif,. Class, etc.) to build all the resources in advance.
- Some methods should provide information about the given JAR file itself (basically
ZipFile
Information, including the number of JAR/zip entries, the enumerator that returns all resource names, and the read method that returns the length of specific entries (and other attributes; the read method that allows indexing is just a few examples.
- Pair
JarResources
To be used by the applet. By using applet parameters andURLConnection
To download the jar content from the network, rather than opening the file as a local file. In addition, we can extend this class to a custom Java content handler.
Summary
If you were eager to know how to extract images from a jar file, you have learned a method. With this new class provided by this technique, you can not only use jar files to process images, but also use the extraction magic in jar files.AnyResources.
Author Profile Arthur Choi is currently a consultant at IBM. He has worked in several companies, including Samsung network laboratory and Mitre. He has participated in the following projects: Client/Server systems, distributed object computing, and network management. He has used multiple languages in various operating system environments. He began programming with fortran iv and COBOL in 1981. Later, he switched to C and C ++, and he has been working in Java for the last two years. The Java applications he is most interested in are the data warehouse in the WAN and parallel processing and distributed processing on the Internet (using proxy-based programming ). Reach Arthur's email address is arthur.choi@javaworld.com.John Mitchell, who has worked as an employee and consultant and is now the boss of his company, has invested in the development of cutting-edge computer software over the past decade, and has provided advice and training to other developers. His consulting scope covers Java technology, compilers, interpreters, web-based applications, and Internet commerce. John isMaking sense of Java: A Guide for managers and the rest of usOne of the authors of this book, and published many articles in programming magazine. ExceptJavaworldWriteJava tipsIn addition to the column, he also hosts the comp. Lang. TCL. Announce and comp. binaries. geos news groups. Reach John's email address is john.mitchell@javaworld.com. |
Reference resources
- This is a class file
JarResources.java
Jarresources. Java
- Jars
Http://www.javasoft.com/products/jdk/1.1/docs/guide/jar/index.html
- For more information about Java archive support, see "Java tip 21: Use archive files to speed up applet loading"
Http://www.javaworld.com/javatips/jw-javatip21.html