[LWN Logo]

From: cool@eklektix.com
Date: Wed, 21 Oct 1998 00:19:11 GMT
Subject: JDC Tech Tips Vol. 2 No. 3
To: JDCTechTips@sun.com

-WELCOME- to the Java(sm) Developer Connection(sm) Tech Tips.  This issue
covers Jar file manifests and improving I/O performance with buffering.
The JDC Team-


             J  D  C    T E  C  H   T  I  P  S
             
             TIPS, TECHNIQUES, AND SAMPLE CODE
                  * Improving I/O Performance with Buffering 
                  * Jar File Manifests
                  
            
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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

IMPROVING I/O PERFORMANCE WITH BUFFERING.  The execution-time performance
of the Java(tm) programming language is an issue that has received a fair
amount of attention, with various technologies such as Just In Time
Compilation employed as ways of improving performance.

But there are other aspects of performance that depend more on programming
techniques that are applied to a given application.  One of these is using
I/O buffers to improve performance.  A buffer is a storage area where bytes
or characters are accumulated so that I/O can be performed in large chunks
rather than a single byte at a time.  Input or output of single bytes tends
to be quite costly, because of method call overhead and dependencies on the
underlying operating system (such as invocation of system calls).

Also, when output is written to a terminal or screen window, buffering may
be set so that the buffer will be flushed (thereby invoking the underlying
operating system I/O mechanisms) at the end of every line, no matter how
many bytes have accumulated for output.  Such flushing is required for the
application to be used interactively.

To see how buffering works, consider an example of writing to System.out,
which is a PrintStream:

        import java.io.*;
        
        public class fastout {
                public static void main(String args[])
                {
                        FileOutputStream fdout =
                            new FileOutputStream(FileDescriptor.out);
                        BufferedOutputStream bos =
                            new BufferedOutputStream(fdout, 1024);
                        PrintStream ps =
                            new PrintStream(bos, false);
        
                        System.setOut(ps);
        
                        final int N = 100000;
        
                        for (int i = 1; i <= N; i++)
                                System.out.println(i);
        
                        ps.close();
                }
        }

This program writes the values 1...100000 to standard output.  By default,
when System.out is initialized, it is set to the equivalent of:

        FileOutputStream fdout =
            new FileOutputStream(FileDescriptor.out);
        BufferedOutputStream bos =
            new BufferedOutputStream(fdout, 128);
        PrintStream ps =
            new PrintStream(bos, true);
        
        System.setOut(ps);

This results in System.out initialized to a PrintStream with a 128-byte
buffer, and with line buffering set so that an output newline character
will result in the buffer being flushed.

But in the program above, the buffer size has been changed to 1024, and the
PrintStream constructor is given arguments so that no line buffering takes
place.  Because of the different buffering scheme, output occurs about
three times faster than with the default.  This is one of several places in
the Java language I/O system where buffering can make a big difference in
performance.

The program also illustrates the technique of redirecting output, using
System.setOut.  Whether this technique is "right" depends on the
application; sometimes line buffering is unimportant, and at other times
using explicit flush calls makes more sense rather than depending on the
I/O system to perform flushing for you.

Note that PrintStream has kind of an odd status at present, in that it has
been partially deprecated in favor of PrintWriter.  But it is still used
extensively, and is still the "official" mechanism for standard output
found in java.lang.System.  However, the above performance tip has general
application to I/O, and can be used in other contexts.


JAR FILE MANIFESTS.  Jar files are mentioned in earlier issues of the JDC
Tech Tips (No.  1 and No.  9), and this issue covers them again.  Jar files
are used extensively within the Java language for packaging and
distribution purposes, and it's important know how they work and how they
can be manipulated.

A Jar file has the same format as a Zip file, and also optionally includes
a manifest, which is a description of the contents of the file.  Jar files
are used by the Java language for several purposes, such as distribution of
groups of .class files, and downloading applets from the Web.


A feature in JDK(tm) 1.2 builds on existing java.util.zip.ZipFile
functionality, to explicitly support the manipulation of Jar file
manifests.  Here is an example of how this feature works:

        import java.io.*;
        import java.util.*;
        import java.util.jar.*;
        
        public class manif {
                public static void main(String args[])
                {
                        if (args.length != 1) {
                                System.err.println("usage: manif file.jar");
                                System.exit(1);
                        }
        
                        try {
                                JarFile jf = new JarFile(args[0]);
                                Manifest manif = jf.getManifest();
                                if (manif != null) {
                                        manif.write(System.out);
                                        Attributes attr =
                                            manif.getMainAttributes();
                                        String attrname =
                                            "Specification-Version";
                                        String str =
                                            attr.getValue(attrname);
                                        System.out.println(str);
                                }
                        }
                        catch (IOException e) {
                                System.err.println(e);
                        }
                }
        }

JarFile is a class whose instances represent Jar files.  In the example
given above, a Jar file is opened for access, and then the manifest is
written to standard output.  Next, the value of an individual attribute of
the manifest ("Specification-Version") is retrieved and displayed.  Output,
when the program is run on the JDK 1.2 Beta 4 version of "rt.jar", looks
like this:

        Manifest-Version: 1.0
        Specification-Title: Java Platform API Specification
        Specification-Vendor: Sun Microsystems, Inc.
        Implementation-Vendor: Sun Microsystems, Inc.
        Specification-Version: 1.2beta4
        Implementation-Version: 1.2beta4
        Implementation-Title: Java Runtime Environment
        
        1.2beta4

Manifest attributes can be used both globally (they apply to the whole Jar
file), and per entry (attributes of a given entry in the Jar file).

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-- 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 --

The JDC Tech Tips are sent to you because you elected to subscribe when you
registered as a JDC member.  To unsubscribe from JDC Email, go to the
following address and enter the email address you wish to remove from the
mailing list:

http://developer.java.sun.com/unsubscribe.html 

-- ARCHIVES -- 

You'll find the JDC Tech Tips archives at:

http://developer.java.sun.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.java.sun.com/developer/copyright.html


The JDC Tech Tips are written by Glen McCluskey.


JDC Tech Tips Vol. 2 No. 3
October 20, 1998