Download Java, A Beginners Guid - Chatper 10

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java, A Beginner's Guide
Fifth Edition
by Herbert Schildt
Chapter 10
This chapter covers the I/O (Input/Output) system in Java. The I/O system covers things from
console input and output to file input and output. By default, the I/O system in Java uses Byte
streams, but character streams have been added in modern Java to make character input and
output easier and more efficient.
Java's I/O Is Built upon Streams
All input and output in Java is based on "streams." A stream is an abstract object that identifies
information coming in or going from Java. You will notice all the input and output operations in
this chapter use some kind of Stream object at some level.
Byte Streams and Character Streams
As mentioned earlier, modem Java handles I/O in either Byte or Character form. At a low-level,
everything is handled in Bytes. However, Java provides a Character interface to all of the
streams to allow direct Character input and output to be handled. Otherwise your program would
have to do Byte conversions whenever doing I/O operations. The Character stream is the
generally preferred method for professional, commercial, programming. Byte streams are
common in quick programs and debugging.
The Byte Stream Classes
This section introduces the Byte Stream classes. The top of these classes are the InputStream
nd OutputStream classes, which handle input and output of Bytes. Page 328 of the book has a
table of Byte Stream classes that are useful.
The Character Stream Classes
This section introduces the Character Stream classes. The top of these classes are the Reader
and Writer classes, which handle input and output of Characters. Page 329 of the book has a
table of Character Stream classes that are useful.
The Predefined Streams
There are predefined streams in Java that you have already been interacting with, such as
System.out to print to the console. There is also System.in (which we saw earlier as well) and
System.err. These three are attached to what is commonly called standard input (generally the
user's keyboard), standard output (generally a shell or console the user is executing Java from)
and standard error (generally the same as standard output, but can be different).
Using the Byte Streams
To use Byte Streams you will create instances of the InputStream and OutputStream, depending
on whether you want to take input or send output of Bytes. These two classes potentially throw
an IOException, which can be caught using the methods from chapter 9.
Reading Console Input
As we saw in the predefined streams section, System.in provides us access to an input
stream. System.in is actually an instance of InputStream and we can read directly from it
using the read( ) method.
Syntax
System.in.read( );
You can also specify a Byte array to read into, which the InputStream will store Bytes to
until the array has been filled (if you declare the array as a size 5 you will get up to 5
Bytes into that array). It is also possibly to specify a Byte array and a start integer and
max integer, telling the InputStream to start reading at the start integer Bytes (if you
specify 5 here, you will get Bytes starting at the 5th Byte) and reading max integer number
of bytes (if you specify 3 here you will get 3 Bytes).
See page 331 for more information on the various read methods. Pages 331 and 332
have a quick example as well.
Writing Console Output
System.out is an OutputStream object and can be used to write to the console. We have
done this pretty extensively so far using the print( ) method. In this section, the write( )
method is introduced.
Syntax
System.out.write(b);
The print( ) method is generally a Character Stream wrapper of the Byte OutputStream.
Here we specify b to write, which is an integer value. Another thing of note is that an
integer can be up to 32 bits in width where a Byte is limited to 8 bits. Since we know that
the write( ) method is a Byte stream, it cannot handle all 32 bits of an integer, so it only
takes the first 8 bits. You may get some funky results if you pass integers using greater
than 8 bits to the write( ) method.
Reading and Writing Files Using Byte Streams
In the above section we used the console as an example, this section introduces using files rather
than the console. To use a file for a Byte Stream, you will use the FileInputStream and
FileOutputStream classes.
Inputting from a File
To input from a file, you will use an instance of the FileInputStream class.
Constructor
FileInputStream(String filename) throws FileNotFoundException;
Above is the constructor of the FileInputStream class. You can see it takes a String
parameter of filename. It also potentially throws a FileNotFoundException, if the file does
not exist or Java cannot read the file for some reason (corruption or permissions
perhaps).
Once you have the file open, you can use the same read( ) method described in the
console section above to read Bytes from the file.
To close the file, which you will want to do once you are done with it, call the close( )
method. This method has no parameters. If you do not close the file when you are done
with it, it will remain in memory consuming resources that are not likely in use.
This section shows many examples of reading a file and using the try, catch and finally
block to handle the FileNotFoundException and closing the file after you are done with it.
See pages 334 through 336 for examples.
Writing to a File
To write to a file, you will use the FileOutputStream class.
Constructors
FileOutputStream(String filename) throws FileNotFoundException;
FileOutputStream(String filename, Boolean append) throws
FileNotFoundException;
Above are two common constructors for the FileOutputStream class. Both take a String
parameter of the file name to open for output. One constructor adds a Boolean append
parameter, which tells FileOutputStream whether to overwrite (False) or write to the end
(True) of a file. Both potentially throw the FileNotFoundException we saw in the
FileInputStream class.
Once the file is open, we can use the same write( ) method we saw with the
OutputStream example with the console.
As with the FileInputStream, there is a close( ) method that you will want to call when you
are done with the file.
See pages 338 and 339 for an example of FileOutputStream.
Automatically Closing a File
JDK 7 has added a new feature that will automatically close a file when you are done with it,
which uses the try-by-resource mentioned in chapter 9.
Syntax
try (resource-specification) {
}
Above is the general syntax for try-by-resource. The resource-specification is an I/O object of
some sort (FileInputStream, FileOutputStream, ETC). The resource used must be
AutoCloseable, as defined in the AutoCloseable interface in the java.lang package. With this try
block, you do not need to explicitly call the close( ) method of the resource you are working with,
Java will automatically do it for you. However, the resource will not be available outside of the try
block.
See pages 339 through 341 for examples.
Reading and Writing Binary Data
This section covers reading and writing in the primitive Java data types, not just binary. Ther4e
are two new classes that help facilitate reading and writing in these primitive types;
DataInputStream and DataOutputStream.
Constructor
DataOutputStream(OutputStream outputStream);
Above is the constructor for the DataOutputStream class, notice that it takes an input of an
OutputStream object, so you must wrap it around an existing OutputStream object.
The DataInputStream constructor is the same as the DataOutputStream, except it accepts an
InputStream object instead.
There are two tables, on page 342 and 343, covering the methods for the DataOutputStream and
DataInputStream classes.
See pages 343 through 345 for examples.
A File Comparison Utility
An example program that uses FileInputStream to compare two files to see if they are different.
Random-Access Files
The classes introduced so far are intended to read and write files in sequential order. Java also
provides a RandomAccessFile class that allows data in files to be accessed in random order,
introducing new methods such as the seek( ) method.
Constructor
RandomAccessFile(String filename, String access) throws FileNotFoundException;
The constructor for RandomAccessFile takes two String parameters, the filename you are
opening and the access method for that file. The access method can be r (read) or read-write
(rw), for example.
One new method introduced is the seek( ) method, which facilitates the "random" access to the
data in the file.
Method
seek(long newPos) throws IOException;
The seek method takes one parameter, a long value of the newPos which is the new position in
the file you wish to access. If you put 0 as the newPos value, the pointer will move to the
beginning of the file where you can read from or write to the beginning of the file.
See pages 347 and 348 for examples.
Using Java's Character-Based Streams
This section uses the Character stream rather than the Byte stream seen earlier in the chapter to
read and write from the console.
Console Input Using Character Streams
Console input is generally handled through System.in, but this is a Byte stream. For this
example, we want to use a Character Stream. The book mentioned earlier in the chapter
that the Character Streams are parallel to the Byte Streams, and, in fact, a Character
Stream simply wraps an existing Byte Stream.
To get a Character Stream from System.in, we will want to use some instance of the
Reader class. The book claims the BufferedReader is the best class for this task, we'll
take their word for it.
Constructor
BufferedReader(Reader inputReader);
The BufferedReader class takes a single parameter of Reader type, so we will need to
conver the System.in object from an InputStream to a type compatible with Reader. The
most direct option is to use the InputStreamReader class.
Constructor
InputStreamReader(InputStream inputStream);
So to get a Character stream from System.in, we would want to create an
InputStreamReader and then pass that to the BufferedReader.
Example
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
From here we have an object stored in the identifier named br that is a Character Stream
of our console input. We can now read Characters rather than Bytes using the read( )
method. You have the same three options with this read( ) method; read one character,
read x characters into character array and read x characters into a character array
starting at y position.
A new method with BufferedReader is the readLine( ) method, which will read a string.
This method looks for a new line character to determine what it reads and retrurns.
See pages 351 and 352 for examples.
Console Output Using Character Streams
System.out, like System.in, is a Byte Stream. We want to get a Character Stream of the
System.out to output to the console using a Character Stream. To do this, we will use
the PrintWriter class, there is actually a BufferedWriter class too but the PrintWriter is
easier to use in this case.
Constructor
PrintWriter(OutputStream outputStream, boolean flushOnNewLine);
The PrintWriter constructor is fairly simple to use, compared to the BufferedReader in the
previous section. You can pass the System.out object directly to the class, as it takes an
OutputStream input. The second parameter tells PrintWriter to flush the buffer on a new
line (True) or buffer until explicitly told to flush (False). The difference on the flush is
when the output is actually sent to the console, if you set this option to true each line will
be printed to the console as they arrive. Otherwise, the output will not be printed to the
console until the flush( ) method is called.
Another thing to note is that this class does not throw exceptions, you will have to call the
checkError( ) method to see if there were any problems.
Once you have a PrintWriter object, you can use the print( ) and println( ) methods to
write to the console. If you pass any other object types, other than primitive, in the print( )
or println( ) methods, PrintWriter will attempt to call the toString( ) method on that object
to get the string value.
See page 353 for examples.
File I/O Using Character Streams
This section covers file I/O with Character Streams, rather than Byte Steams. There are two new
classes introduced to accomplish this task; FileReader and FileWriter.
Using a FileWriter
Constructors
FileWriter(String filename) throws IOException;
FileWriter(String fielname, boolean append) throws IOException;
These are the two most common constructors for FileWriter, you'll notice their similarity to
the FileOutputStream constructors.
Once you have a FileWriter object, you can use the write( ) method to write strings to the
file. You will want to call the close( ) method when you are done with the file, or use the
try-by-resource method in JDK 7.
Using a FileReader
Constructor
FileReader(String filename) throws FileNotFoundException;
Above is the most common constructor, it takes one String parameter of the filename to
read.
Once you have an instance of the FileReader class, you can pass it to a BufferedReader
object to read the file, and then use the read( ) and readLine( ) methods.
See pages 355 and 356 for examples.
Using Java's Type Wrappers to Convert Numeric Strings
Java provides a number of wrapper classes to convert numeric strings, and other types such as
Boolean. These wrapper classes are designed around the primitive classes and generally have a
parse method to convert the data types. For instance, you can convert a string that contains an
integer to the integer class using Integer.parseInt(string).
See the table on page 357 for a list of wrappers and pages 357 and 358 for examples.
Creating a Disk-Based Help System
This section converts the help system created earlier in the book using the new I/O classes
covered in chapter 10. This system uses flat text files to drive the system rather than coding in
the text and menus.