Received: from PACIFIC-CARRIER-ANNEX.MIT.EDU by po10.MIT.EDU (5.61/4.7) id AA09446; Wed, 21 Oct 98 02:15:02 EDT Received: from hermes.javasoft.com by MIT.EDU with SMTP id AA05703; Wed, 21 Oct 98 02:14:57 EDT Received: by hermes.java.sun.com (SMI-8.6/SMI-SVR4) id GAA18362; Wed, 21 Oct 1998 06:26:11 GMT Date: Wed, 21 Oct 1998 06:26:11 GMT Message-Id: <199810210626.GAA18362@hermes.java.sun.com> X-Mailing: 19 From: JDCTechTips@sun.com Subject: JDC Tech Tips Vol. 2 No. 3 To: JDCTechTips@sun.com Reply-To: JDCTechTips@sun.com Errors-To: JDCMailErrors@sun.com Precedence: junk Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Beyond Email 1.0 -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