# JDC Tech Tips No. 9

JDCTechTips@sun.com
Wed, 22 Apr 1998 22:47:30 GMT

- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: Jerry Jongerius: "Problem using a custom class loader in a trusted applet"
- Previous message: Paul Krier: "Exportable Security"

    Date: Wed, 22 Apr 1998 22:47:30 GMT

    Message-Id: <199804222247.WAA19445@hermes.javasoft.com>

    From: JDCTechTips@sun.com

    Subject: JDC Tech Tips No. 9

    To: JDCTechTips@sun.com

-WELCOME- to the Java(sm) Developer Connection(sm) Tech Tips. This issue
covers using Java Collections and unpacking Zip Files. The JDC Team-

J D C T E C H T I P S
TIPS, TECHNIQUES, AND SAMPLE CODE
* Using Java Collections
* Unpacking Zip Files

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
T I P S , T E C H N I Q U E S , A N D S A M P L E C O D E

USING JAVA COLLECTIONS. The Collection interface is a new feature of
JDK(tm) 1.2. A "collection" in data structure terms is a group of
elements. Some types of collections that derive from Collection include
the following:

List -- an interface specifying an ordered sequence of elements

Set -- an interface specifying a mathematical set of elements, with no
duplication

Vector -- an implementation of List

Specifying interfaces in this way lets you manipulate collections without
having to know the details of how a given collection is implemented. Note
that existing data types like Vector have been incorporated into the
Collection framework.

To see why the collections approach can be useful, consider a simple
example, that of sorting a vector of elements. JDK 1.1 and earlier
versions offered no standard way to do this kind of sorting, but
collections provides the capability. Consider the following example:

import java.util.*;
class Comparer implements Comparator {
public int compare(Object obj1, Object obj2)
{
int i1 = ((Integer)obj1).intValue();
int i2 = ((Integer)obj2).intValue();
return Math.abs(i1) - Math.abs(i2);
}
}
public class collect {
public static void main(String args[])
{
Vector vec = new Vector();
vec.addElement(new Integer(-200));
vec.addElement(new Integer(100));
vec.addElement(new Integer(400));
vec.addElement(new Integer(-300));
Collections.sort(vec);
for (int i = 0; i < vec.size(); i++) {
int e=((Integer)vec.elementAt(i)).intValue();
System.out.println(e);
}
Collections.sort(vec, new Comparer());
for (int i = 0; i < vec.size(); i++) {
int e=((Integer)vec.elementAt(i)).intValue();
System.out.println(e);
}
}
}

In this example, there is a vector of Integer wrappers on integral
quantities. Calling Collections.sort on this vector sorts the vector in a
natural way, that is, from lowest to highest according to the values
contained in the wrappers. This sorting is achieved by virtue of the fact
that all the wrapper types, along with String and a few others, implement
an interface called java.lang.Comparable that imposes an ordering on
individual elements. And Vector is an implementation of List, which
defines a sorting method on lists.

But suppose you want to sort this vector according to your own ordering,
one that compares elements according to their absolute magnitude. How can
you do this?

One approach is to call Collections.sort again, this time specifying your
own ordering. This ordering is done by defining a class "Comparer" that
implements the java.util.Comparator interface, returning < 0, 0, or > 0
according to whether the first element is less than, equal to, or greater
than the second. The difference between java.lang.Comparable and
java.util.Comparator is simply that Comparable is used for types (such as
Integer and String) that are built in to the core API, while Comparator is
used in cases where you want to specify your own custom element ordering.

Also, there are other features in collections worth investigating, such as
the Map interface that replaces Dictionary and binary searches on ordered
lists. The benefit of the collection framework is that it provides easier
and more powerful use of Java language data structures.

UNPACKING ZIP FILES. Zip files are used widely for packaging and
distributing software. ZipFile is a handy tool for doing the following:
reading the contents of .zip and .jar files, obtaining a list of the files
they contain, and reading the contents of individual files. Jar files,
used in Java software distribution, employ the Zip file format as well.
For more information on Jar files, see JDC Tech Tips No. 1 (September 3,
1997) at the following address:

http://developer.javasoft.com/developer/technicalArticles/TechTips/

java.util.ZipFile is a class used to represent a Zip file. You construct a
ZipFile object, and then iterate over the entries in the file, each of
which is a ZipEntry. Entries can be checked to determine if they are
directories and read from as if they were individual files, in addition to
other functions. The ZipFile class is found in both JDK 1.1 and JDK 1.2
beta2.

Here is an example of using ZipFile to dump out the entries and contents of
a .zip file. The program accepts a single file argument, along with an
optional -contents flag that indicates the contents should also be
displayed (note that printing a binary file to screen does not work well).

import java.io.*;
import java.util.Enumeration;
import java.util.zip.*;
public class zipview {
public static void dump(ZipFile zf, ZipEntry ze)
throws IOException
{
System.out.println(">>>>> " + ze.getName());
InputStream istr = zf.getInputStream(ze);
BufferedInputStream bis =
new BufferedInputStream(istr);
FileDescriptor out = FileDescriptor.out;
FileOutputStream fos = new FileOutputStream(out);
int sz = (int)ze.getSize();
final int N = 1024;
byte buf[] = new byte[N];
int ln = 0;
while (sz > 0 && // workaround for bug
(ln = bis.read(buf, 0, Math.min(N, sz))) != -1) {
fos.write(buf, 0, ln);
sz -= ln;
}
bis.close();
fos.flush();
}
public static void main(String args[])
{
boolean dump_contents = false;
int arg_indx = 0;
ZipFile zf = null;
if (args.length >= 1 && args[0].equals("-contents")) {
dump_contents = true;
arg_indx++;
}
if (arg_indx >= args.length) {
System.err.println("usage: [-contents] file");
System.exit(1);
}
try {
zf = new ZipFile(args[arg_indx]);
}
catch (ZipException e1) {
System.err.println("exception: " + e1);
}
catch (IOException e2) {
System.err.println("exception: " + e2);
}
Enumeration list = zf.entries();
while (list.hasMoreElements()) {
ZipEntry ze = (ZipEntry)list.nextElement();
if (!dump_contents || ze.isDirectory()) {
System.out.println(ze.getName());
continue;
}
try {
dump(zf, ze);
}
catch (IOException e) {
System.err.println("exception: " + e);
}
}
}
}

This program includes a workaround for a bug in JDK versions 1.1 and 1.2
beta 2, that is, bug #4040920 in the JDC Bug Parade database. Normally,
when you read from a low-level file input stream, you read chunks of, say,
1024 bytes at a time, and you don't worry whether that many bytes are
actually left to read. This approach fails with the input stream returned
by getInputStream for a given Zip file entry, and the workaround is to
never try to read more bytes from the entry than are actually there.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-- EDITOR'S NOTE --

The names on the JDC mailing list are used for internal Sun
Microsystems(tm) purposes only. To remove your name from the list, see
SUBSCRIBE/UNSUBSCRIBE below.

-- FEEDBACK --

Comments? Send your feedback on the JDC Tech Tips to:

JDCTechTips@Sun.com

-- SUBSCRIBE/UNSUBSCRIBE --

If you want to unsubscribe from JDC Email, sign in to the JDC. Then click
"Change account information." Type your password, and uncheck the box at
the end of the form that says "It's okay to send me JDC Email." The JDC
sign-in address is:

http://java.sun.com/jdc

-- ARCHIVES --

You'll find the JDC Tech Tips archives at:

http://developer.javasoft.com/developer/javaInDepth/TechTips/index.html

-- COPYRIGHT --

Copyright 1998 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.

This document is protected by copyright. For more information, see:

http://developer.javasoft.com/developer/copyright.html

The JDC Tech Tips are written by Glen McCluskey.

JDC Tech Tips No. 9
April 21, 1998

- Next message: Jerry Jongerius: "Problem using a custom class loader in a trusted applet"
- Previous message: Paul Krier: "Exportable Security"