Purpose Setup Creating an output stream

Lab 29 ? Stream i/o

Purpose

This laboratory introduces some of the java.io classes for stream i/o.

Setup

? Download into your nhLab directory and unzip. ? You should now have a subdirectory in your nhLab directory named lab29. ? Open DrJava. If DrJava is already open, close all open documents (Close All from the File pull-down menu) and

clear the interactions history by choosing the Clear Interactions History option from the Tools pull-down menu.

Creating an output stream

The standard package java.io contains the basic predefined facilities for reading and writing data streams. The classes that support reading and writing from data streams are organized into four categories:

? InputStream classes for reading byte streams;

? OutputStream classes for writing byte streams;

? Reader classes for reading character streams;

? Writer classes for writing character streams.

We start by creating a method that writes a byte stream. The method will simply read five integers from the keyboard and write the integer values (as 32-bit binary values) to a file.

? Open the file Utility.java. This file contains the stub of a method writeFile. Note that the parameter is a java.io.File. Note also that the method header includes a throws clause. Several operations to be included in the method can throw a java.io.IOException.

? Edit the method writeFile so that it creates a Scanner reading from System.in, and reads five integers from standard input echoing them to standard output.

? Save, compile, and test informally in the interactions pane. Even though we are not yet using the File argument, we will need to create one to invoke the method.

> import nhLab.lab29.*; > import java.io.*; > File f = new File("temp"); > Utility.writeFile(f);

To write binary file, we use an OutputStream. OutputStream is an abstract class that serves as the basis for building classes to write byte streams.

A DataOutputStream wraps (i.e., has as a component) an OutputStream and adds the functionality of writing primitive values (as binary values) to the OutputStream.

DataOutputStream

wraps

OutputStream

The OutputStream is given as an argument to the DataOutputStream constructor: public DataOutputStream (OutputStream out)

DataOutputStream includes methods such as public void writeBoolean (boolean v) throws IOException Write a boolean to the underlying output stream as a 1-byte value.

-1-

public void writeDouble double v) throws IOException Write a double to the underlying output stream as an 8-byte quantity.

public void writeInt (int v) throws IOException Write an int to the underlying output stream as four bytes.

Realize that these methods do not write character representations of the values to the file. Rather they write binary values. They throw an exception if an i/o error occurs. DataOutputStream is also a subclass of OutputStream.

OutputStream

DataOutputStream

Thus a DataOutputStream can be wrapped by another object that wraps an OutputStream. The class FileOutputStream extends OutputStream by allowing a file to be specified as the destination of the output. In particular, one of the FileOutputStream constructors takes a File argument:

public FileOutputStream (File file) throws FileNotFoundException This method throws a java.io.FileNotFoundException if the specified File does not exist or cannot be created. FileNotFoundException is a subclass of IOException. Since a FileOutputStream is a subtype of OutputStream, a FileOutputStream can be wrapped in a DataOutputStream. ? Complete the method writeFile. The method should create DataOutputStream and use its writeInt

method to write the five integers into the specified file. Invoke the DataOutputStream method close to close the stream before the method completes. Save and compile. ? Invoke the method form the interactions pane. We do not yet have an easy way to look at the contents of the file, but we can at lease make sure that 20 bytes were written. The File method length gives the size of the file in bytes.

> import nhLab.lab29.*; > import java.io.*; > File f = new File("temp"); > Utility.writeFile(f); ... > f.length()

Creating an input stream

Now we'll write a method that displays the contents of the file we created above. To read a binary file, we use an InputStream. Like OutputStream, InputStream is an abstract base class. The classes FileInputStream and DataInputStream mirror the output classes used above. Both are subclasses of InputStream. FileInputStream allows a file to be specified as the input source. One of its constructors simply takes a File argument.

public FileInputStream (File file) throws FileNotFoundException A DataInputStream wraps an InputStream.

public DataInputStream (InputStream in) It provides method for reading binary values written by a DataOutputStream. Some of its methods are as follows.

-2-

public char readChar () throws IOException, EOFException Read two bytes and return the value as a Unicode character.

public double readDouble () throws IOException, EOFException Read eight bytes and return the value as a double.

public int readInt () throws IOException, EOFException Read four bytes and return the value as an int.

public int readUnsignedByte () throws IOException, EOFException Read and return one input byte. The byte is interpreted as an unsigned integer in the range 0 through 255, inclusive.

? Look at the method displayFile in the Utility class. This method will display the contents of a binary file. We want to show the bytes as strings of 0's and 1's. We'll write four bytes to a line so that we can easily "see" the integers. We expect the output to look something like this:

00000000 00000000 00000000 00000001 11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000101 11111111 11111111 11111111 11111010

? Complete the method displayFile. Here are some suggestions.

? Use the DataInputFile method readUnsignedByte to read the bytes. ? The only way to tell that the entire file has been read is to catch the EOFException thrown by the read

method. This exception is thrown when the method is invoked and there is no more data to be read from the file. Thus the read method should be enclosed in a try statement. Catch the EOFException, do a println if necessary, close the input file, and end the method. (Note that this violates the rule that the only legitimate ways to respond to an exception are to try again, or to throw or propagate an exception. Ah well. Too bad there is no "endOfFile" method.) ? If b is the int returned by readUnsignedByte, it can be converted to a String, by invoking the method Integer.toString(b,2). However, the resulting String will not have unnecessary leading zeros. The method pad in Utility will stick the leading 0's on. ? As you write out the bytes, count to 4 and invoke System.out.println after each four bytes are written.

? Save, compile, and test informally in the interactions pane. When you create the file, use 1, -1, and the maximum and minimum integers in your data.

> import nhLab.lab29.*; > import java.io.*; > File f = new File("temp"); > Integer.MAX_VALUE > Integer.MIN_VALUE > Utility.writeFile(f); ... > Utility.displayFile(f)

What to submit

If directed by your instructor, turn in a listing of the modified class Utility. Your instructor might also require that you turn in the interactions history. You can save the interactions history by selecting the Save Interactions History... option from the Tools pull-down menu. Be sure everything you turn in is clearly labeled with your name and section number.

-3-

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download