java.util.Zip

I

Ike

Is anyone aware of where I can find an example of listing the contents of -
and reading an individual file within a zip file?

Thanks, Ike
 
I

Ike

//I found this - exactly what I was looking for...it looks worth repeating
esp if someone hits my original post via a search on a similar problem in
the future - Ike


Java Tip 49: How to extract Java resources from JAR
and zip archives

Are you new to the JAR file scene? This new class will help
you out!

Summary
Bundling an assortment of Java resources in a Java ARchive (JAR)
file is an excellent way to reduce download time,
increase security, and increase manageability. This tip shows you
how to easily extract the resources from JAR files
for your own use. (1,300 words)



By John D. Mitchell and Arthur Choi



ost Java programmers are pretty clear on the advantages of using a
JAR file to bundle up all of the various resources (that
is, .class files, sounds, and images) that comprise their Java
solution. (If you're not familiar with JAR files, check out the
Resources section below.) A very common question asked by people who are
just starting to incorporate JAR files into their bag
of tricks is, "How do I extract an image from a JAR?" We're going to
answer that question and provide a class to make it super
simple to extract any resource from a JAR!

Loading a GIF image
Let's say we have a JAR file containing a bunch of .gif image files that
we want to use in our application. Here's how we could
access an image file from the JAR using the JarResources:

JarResources jar = new JarResources ("Images.jar");
Image logo =
Toolkit.getDefaultToolkit().createImage (jar.getResource
("logo.gif");

That code snippet shows that we can create a JarResources object
initialized to the JAR file containing the resource that
we're interested in using -- Images.jar. We then use the JarResources'
getResource() method to provide the
raw data from the logo.gif file for the AWT toolkit's createImage()
method.

A note on naming
The JarResource is a reasonably straightforward example of how to use
various facilities provided by Java 1.1 to manipulate JAR
and zip archive files.

A quick note about naming. Archiving support in Java actually started
out using the popular zip archiving format (check out "Java
Tip 21: Use archive files to speed up applet loading"). So, originally,
in implementing Java support to manipulate the archive files,
all of the classes and whatnot were placed in the java.util.zip package;
these classes tend to start with "Zip." But somewhere in
the move to Java 1.1, the powers that be changed the name of the archive
to be more Java focused. Hence, what we now call
JAR files basically are zip files.

How it works
The important data fields for the JarResources class are used to track
and store the contents 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;

So, the instantiation of the class sets the name of the JAR file and
then calls off to the init() method to do all of real work:

public JarResources(String jarFileName) {
this.jarFileName=jarFileName;
init();
}

Now, the init() method pretty much just loads in the entire contents of
the specified JAR file into a hashtable (accessed via
the name of the resource).

This is a fairly hefty method, so let's break it down a bit further. The
ZipFile class gives us basic access to the JAR/zip archive
header information. This is similar to the directory information in a
file system. Here we enumerate through all of the entries in the
ZipFile and build out the htSizes hashtable with the size of each
resource in the archive:

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 access the archive through the use of the ZipInputStream class.
The ZipInputStream class does all of the
magic to allow us to read each of the individual resources in the
archive. We read the exact number of bytes from the archive that
comprise each resource and store that data into the htJarContents
hashtable accessible by resource name:

FileInputStream fis=new FileInputStream(jarFileName);
BufferedInputStream bis=new BufferedInputStream(fis);
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 means unknown size.
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 to 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 archive, not, for example, the
name of a class in a package -- that is, the ZipEntry class from the
java.util.zip package would be named
"java/util/zip/ZipEntry," rather than "java.util.zip.ZipEntry."

The final important part of the code is the simple test driver. The test
driver is a simple application that takes a JAR/zip archive
name and the name of a resource. It tries to find the resource in the
archive and reports its 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+").");
}
}
} // End of JarResources class.

And there you have it. A simple-to-use class that hides all of the
messiness involved with using resources tucked away in JAR
files.
 
C

Chris Smith

Ike said:
Is anyone aware of where I can find an example of listing the contents of -
and reading an individual file within a zip file?

Right here:

public void listFiles(File zipFile)
{
ZipFile f = new ZipFile(zipFile);

try
{
Enumeration e = f.entries();

while (e.hasMoreElements())
{
ZipEntry entry = (ZipEntry) e.next();
System.out.println(entry.getName());
}
}
finally
{
f.close();
}
}

To read the file, create the ZipFile as above, but call getEntry(String)
to get a specific ZipEntry by name, and then getInputStream(ZipEntry) to
read the contents of that entry... and remember to still close the
ZipFile when you're done.

Exception handling will be needed, but is omitted because I can't
possibly know enough about your application to figure out the best way
to do it.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top