Java 1.1 Unleashed
- 36 -
|
Option | Description |
v | Tells jar to generate verbose output about the actions it is performing. |
f | Specifies the filename to manipulate. If this option is not given, jar writes to standard output. |
http://www.javasoft.com/products/JDK/1.1/docs/guide/jar/manifest.html
Free ZIP and unZIP programs are available from the Info-ZIP group. Source code and binaries for many platforms are available from this site:
http://www.cdrom.com/pub/infozip/Info-Zip.html
To create an archive, you use jar with the c flag. Suppose that we want to create a JAR file with three files: sampleApplet.class, a Java class file; sampleGraphic.gif, an image file; and sampleSound.au, an audio file. The following command places these three files into an archive named sample.jar. The options cvf specify that we want to create an archive, we want verbose output, and the archive filename should be sample.jar.
% jar cvf sample.jar sample.jar sampleApplet.class sampleGraphic.gif sampleSound.au
Here's what jar shows you as it's creating the archive:
adding: sampleApplet.class in=4480 out=2065 deflated 53.0% adding: sampleGraphic.gif in=506 out=419 deflated 17.0% adding: sampleSound.au in=5529 out=1088 deflated 80.0%
For each file, jar specifies the input size before compression and the output size after compression, as well as a ratio showing how well the file was compressed.
Next, let's list the contents of the archive file we just created. The t option tells jar that we want a table of contents for the JAR file; the vf options specify verbose mode and the filename for which we want information:
% jar tvf sample.jar
Here's the output from jar:
402 Tue Feb 18 23:12:10 EST 1997 META-INF/MANIFEST.MF 4480 Mon Feb 17 02:03:46 EST 1997 sampleApplet.class 506 Tue Feb 18 22:24:52 EST 1997 sampleGraphic.gif 5529 Mon Feb 17 00:16:02 EST 1997 sampleSound.au
Notice that there is an extra file named META-INF/MANIFEST.MF in the JAR archive file. This is a manifest of all the files contained in the archive and a message digest of the contents of each file (see Chapter 37, "Code Signing and JAR Security," for more information about message digests). The jar tool automatically generates a manifest file; alternatively, you can generate one yourself and pass the m flag to jar when you create the archive.
Now let's extract sampleGraphic.gif from the sample.jar file. In the following command, the vf options are the same as they were in the preceding section (verbose mode and the filename from which you want to extract a file). The x option specifies that we want to extract files. If no extra arguments are given, jar extracts the entire contents of the archive. If arguments are given after the archive name, jar takes those as the names of the files to extract.
% jar xvf sample.jar sampleGraphic.gif
Here's the response from jar concerning the extraction request:
extracted: sampleGraphic.gif in=419 out=506 inflated 17.0%
The java.util.zip package contains several classes that facilitate the manipulation of compressed files.
The ZipFile class provides a way to read the contents of a ZIP archive. There are two constructors: one that takes a String specifying the filename of the archive to open and one that takes a java.io.File object. The getName() method returns the path name of the ZIP file represented by the ZipFile object.
Two methods are provided to obtain ZipEntry objects representing the contents of the ZIP file. The getEntry() method takes a String and returns a ZipEntry for the corresponding file; it returns null if no such file exists in the archive. The entries() method returns a java.util.Enumeration of ZipEntry objects for all the entries in the ZIP file. The getInputStream() method is used to obtain an InputStream for the entry represented by the ZipEntry given as a parameter.
Each file in a ZIP archive can be represented by a ZipEntry object. ZipEntry objects can be obtained for an existing file from a ZipFile or ZipInputStream object; they can also be created when you make a new ZIP archive with a ZipOutputStream. The ZipEntry class provides methods to retrieve information about the entry (for example, the filename, the compressed and uncompressed size of the file, and the compression method used for the file). The isDirectory() method is provided to determine whether the entry in question is a normal file or a directory.
In addition to the ZipFile class, the java.util.zip package has two stream classes that handle compressed data. The stream classes in java.util.zip extend either InflaterInputStream or DeflatorOutputStream as appropriate. These two filtered streams provide a generic interface for handling compressed data.
ZipInputStream reads data in the ZIP format from an InputStream. The getNextEntry() method returns a ZipEntry for the next component in the ZIP file and places the stream at the beginning of the data for that component. The closeEntry() method closes the current entry and advances the stream to return the next entry in the archive. Both methods throw a ZipException if a ZIP-related exception occurs.
The ZipOutputStream provides OutputStream functionality for writing compressed data. The putNextEntry() method takes a ZipEntry as a parameter. A new entry is created in the ZIP file and any data written to the stream goes to the current entry. Two methods are provided to control the compression used to store entries: setMethod() takes as a parameter either ZipOutputStream.DEFLATED (to specify that the next entries should be compressed) or ZipOutputStream.STORED (to specify that any subsequent entries should simply be stored with no compression). The setLevel() method takes an integer from 0 to 9, inclusive, with higher numbers indicating more compression (which takes longer to compress). The setComment() method allows the ZIP file comment to be set.
In addition to classes for the ZIP compression format, the java.util.zip package provides two classes that support reading and writing files in the GNU Zip format. GNU Zip is a widely used compression format for UNIX. Unlike the ZIP format, the GNU Zip format handles only one file at a time, rather than multiple files and a directory structure. GNU Zip is most often used as a replacement for the UNIX compress utility, so there is no getNextEntry() method for the GZIPInputStream class. In addition, the GZIPOutputStream has no way to specify filenames for entries.
A new attribute has been added to the HTML <applet> tag: archives. This tag specifies one or more JAR files that should be downloaded with the applet (obviously, these JAR files contain components needed by the applet). You should still specify the code attribute, even if you give the archives attribute because code is used as the name of the applet class to load. Whenever the applet requests a class, image, or sound file, the archives specified are searched first. If the necessary resource is not contained in one of the JAR files downloaded, the applet contacts the server and searches for the resource as it did with the JDK version 1.0.2. You can specify multiple archive files by separating the filenames with + (a plus sign). A sample applet tag is shown in Listing 36.1.
<applet code="sampleApplet.class" archives="sample.jar + icons.jar + commonClasses.jar" width="550" height="300"> <param name="animal" value="lemur"> <param name="server" value="qa.nowhere.com"> </applet>
JAR files provide a way to simplify applet distribution. Along with the new code-signing facilities, JAR files should greatly increase the usefulness of applets by making them easier to distribute and allowing trusted code to step outside the narrow limits of the sandbox. Additionally, the java.util.zip package provides support for manipulating ZIP and GNU Zip archives in any Java program.
©Copyright, Macmillan Computer Publishing. All rights reserved.