Input Stream Wrappers

We have seen several times how a basic I/O class can be wrapped or “decorated” by another I/O class of the same parent class. So it should be no surprise that an InputStream can have a BufferedInputStream and/or a subclass of FilterInputStream interposed between the FileInputStream (or other data source) and the DataInputStream.

There is quite a variety of InputStreams that can decorate the basic access classes. Figure 17-5 shows some, but by no means all, of the most popular classes.

Figure 17-5. Classes that wrap InputStreams

image

You can wrap any or all of the following output streams onto your original InputStream:

  • BufferedInputStream. This class must directly wrap the input source (e.g., the FileInputStream) to get the most performance benefit. You want the buffering to start as early as possible. Wrap any other classes around the buffered input stream.

  • Your subclass of FilterInputStream. You will extend the class and override some or all of the read methods to filter the data on the way in.

  • LineNumberInputStream. This class keeps track of the number of newlines it has seen in the input stream.

  • PushbackInputStream. This class allows an arbitrary amount of data to be “pushed back” or returned to the input stream where it is available for re-reading. You might do this when you are trying to assemble a number out of digits in the input stream and you read past the end of the number.

  • SequenceInputStream. This class provides the effect of gluing several input streams together, one after the other, so that as one stream is exhausted you seamlessly start reading from the next. You might use this when your data is spread across several data files with a similar format.

  • InputStreamReader. This class converts an InputStream class to a Reader class, allowing you to layer any of the Reader classes on top of that. It provides a bridge from the 8-bit byte world to the 16-bit character world when you have an input stream and want a Reader. Remembering that the Reader methods are poor at processing anything with more structure than a character, the most common reason for going from an input stream to a Reader is to change the character set encoding—to convert from, for instance, ASCII to EBCDIC (an ancient IBM codeset).

  • java.util.zip.GZIPInputStream. The zip, gzip, and jar output streams will uncompress the bytes read from them, using the zip, gzip, and jar algorithms, respectively. An example of reading and expanding a file in gzip format is shown in the next section.

  • Various others in the release, and which you write yourself. For example, there is a CipherInputStream that will decrypt what is given to it. This is part of the javax.crypto extension library, which you have to set up with a Cipher object. There is more detail in the online API documentation.

At the very end of the chain of wrapped classes you generally have either a DataInputStream or an ObjectInputStream. The ObjectInputStream class allows you to read back in an object and all the objects it references. You can wrap this class around any of the other input streams, and read the object from a file, a socket, up from a pipe, etc. An example of object I/O is shown in Chapter 18.

gzip files and streams

The word gzip means GNU zip. The GNU organization (a loose organization of expert programmers founded at MIT by officially-recognized-as-a-genius Richard Stallman) has specified a simpler variant of a zip format that has become popular on Unix. It compresses its input by using the patent-free Lempel-Ziv coding. Here's the simplest example code to unpack a gzip file.

//   Expand a .gz file into uncompressed form
//   Peter van der Linden

import java.io.*;
import java.util.zip.*;
public class expandgz {

      public static void main (String args[]) throws Exception {
               if (args.length == 0) {
                       System.out.println("usage:  java expandgz  filename.gz");
                       System.exit(0);
               }
               GZIPInputStream gzi = new GZIPInputStream(
                                               new FileInputStream( args[0] ));
              int to = args[0].lastIndexOf('.'),
              if (to == -1) {
                       System.out.println("usage:  java expandgz  filename.gz");
                       System.exit(0);
               }
               String fout = args[0].substring(0, to);
               BufferedOutputStream bos = new BufferedOutputStream(
                                                 new FileOutputStream(fout) );
               System.out.println("writing " + fout);

               int b;
                do {
                       b = gzi.read();
                       if (b==-1) break;
                       bos.write(b);
               } while (true);
               gzi.close();
               bos.close();
       }
}

Executing this program will expand the gzip file whose name (e.g., abc.gz) is given on the command line. There is a corresponding GZIPOutputStream class that you can use to write a file into compressed gzip form.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.107.25