Internet °ü·Ã ÀÚ·á |
---|
Á¦¸ñ | JDC Tech Tip No.9 1998/04/27 (15:12) |
À̸§ | ±èÈ¿¿ø |
¹øÈ£ | 5 |
Á¶È¸ | 626 |
º»¹® |
Subject: JDC Tech Tips No. 9 Date: Sat, 25 Apr 1998 17:20:22 GMT From: JDCTechTips@sun.com 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 |