(syllabus and calendar)Ch. 10. Using I/0 |
Session 10
If there is time remaining, we can look at extras |
When we first learned how to read, we started with the name of the letters of the alphabet (bytes, chars). Soon, we read words, then sentences, then paragraphs, then entire articles in the Sports section. To read an entire article, we still have to deal with its paragraphs. Consider a newspaper article to be a file, and a paragraph to the chunk of paragraph text we absorb as a page (or screen). Our minds can hold a paragraph of information in short-term memory, which we might consider to be a buffer. Just as we process a two-page article paragraph by paragraph, so Java processes a file by using a buffer.
It is more efficient to reduce input/output operations by grouping the individual elements together for processing. Another analogy might be using a big spoon to eat a set of corn flakes, instead of individual flake by flake, which would be a lot of input operations. Note that many people prefer eating potato chips one-by-one, instead of crushing them into a big spoon. Potato chips are IO-intensive.

This is why most cows prefer to chomp on entire mouthfuls of grass rather than pick at individual potato chips.
Another way to process food is with a stream. Some folks slurp up long spaghetti instead of cutting the noodles. A straw is a wonderful way to stream the contents of a beverage into a mouthful (a buffer).

BufferedReader br = new BufferedReader(new InputStreamReader(System.in);
Think of the straw as System.in, the fluid moving throw the straw as an input stream, and the throat receiving a buffered mouthful/gulp. (An input stream is almost an input straw.)
The input and output facilities of Java include:
The abstract class, java.io.InputStream http://java.sun.com/javase/6/docs/api/java/io/InputStream.html provides implementation methods for managing the bytes in an stream, such as read(byte[] b), mark(int readlimit), reset(), skip(long n), and close(). Therefore, subclasses, such as AudioInputStream and FileInputStream have the choice to reuse the implementation or overwrite it.

The java.io package ( http://java.sun.com/javase/6/docs/api/java/io/package-summary.html ) "Provides for system input and output through data streams, serialization and the file system". The default package, java.lang, provides the most basic I/O functionality. For example, the System class ( http://java.sun.com/javase/6/docs/api/java/lang/System.html ) has a static field, out, the "standard output stream", that enables us to call System.out.println().
However, this output stream derives from the io package, which includes the PrintStream class ( http://java.sun.com/javase/6/docs/api/java/io/PrintStream.html ) with the out field, that supports sending a stream of bytes to a device (such as the console) or a file. Java follows UNIX insofar as standard error, the static err field, is the same device as standard out, and so error reporting automatically takes advantage of the print stream.

Similarly, we get System.in.read() to read from the console from java.io.InputStream - the http://java.sun.com/javase/6/docs/api/java/io/InputStream.html. So the standard input, output, and error streams of java.io are made available to java.io.System. Standard input is given by System.in.
To work with binary data, use a byte stream.
At a higher level, to work with unicode characters, use a character stream. (This is similar to the ftp toggle, binary, which sets the operation to work with bytes instead of characters.)
A char is a convenient way to work with what the system considers to be a byte, and that's why we can convert char to byte and byte to char. Similarly, a character stream is a convenience build on top of a byte stream.
The class java.io.Writer ( http://java.sun.com/javase/6/docs/api/java/io/Writer.html ) is abstract to provide some functionality and some customizability. This class
For example, within the Java APIs, a BufferedWriter, a StringWriter, and a PrintWriter might use different offsets, ways to flush, and close.
If you want to handle ALL the possible I/O exceptions, catch java.io.IOException, ( http://java.sun.com/javase/6/docs/api/java/io/IOException.html ), a direct subclass of java.lang.Exception. This subclass is the superclass of many specialized exceptions, such as java.io.FileNotFoundException.
Reading bytes from the console with a byte array. The byte array can deal with characters.

When we work with arrays, we have the limitation of needing to know the size of the array necessary to store the data. To read in an entire file (and not have to know its size beforehand), read in until the end-of-file (EOF) marker, negative 1 (-1). The read method of java.io.inputStream returns -1 when there is nothing more to read in the file.
Because the read method is on an instance of type FileInputStream, call the constructor for a file input stream. (This class is a subclass of the more general InputStream, which also has a read method.)

Use the Console class so end-users can keep their password hidden from people
near their computer screen. This class is a new feature in the 1.6 version of
Java.
http://download.oracle.com/javase/6/docs/api/java/io/Console.html
We don't have to construct the Console. Instead,
we call the static console method of the
System class, which is
final.
http://download.oracle.com/javase/6/docs/api/java/lang/System.html#console%28%29



A common use case for file IO is to update text, such as the product name. Here, we use a file input stream to demonstrate substitution. Line 76 replaces each blank space with a hypen and saves this to the destination file. To run this program, type java Hypen mySourceFile myDestinationFile


We can compare two files, byte-by-byte, using the read method on a file input stream.


If I run: java FileComparison myLetters.txt
myLetters2.txt
The output is: original says: g but second file says: z

BufferedReader br = new BufferedReader(new InputStreamReader(System.in);
Think of the straw as System.in, the fluid moving throw the straw as an input stream, and the throat receiving a buffered mouthful/gulp. (An input stream is almost an input straw.)
If you know that the file to input or output is not binary but contains characters, use an instance of FileReader, which works with Unicode and supports all the major human languages, including Chinese, Japanese, and Arabic. A FileReader is a subclass of InputStreamReader ( http://java.sun.com/javase/6/docs/api/java/io/InputStreamReader.html ), which works with characters instead of bytes, that can be constructed from a file name.
This version wraps the FileReader inside a BufferedReader which holds a significant amounts of bytes, such as 1024, in a single buffer. Buffering provides efficiency. Without buffering, each invocation of read() or readLine() could fetch at most one line of characters. Assuming you want more than one or two characters, a buffered reader is useful whether reading characters from the console or a file.

This version includes try, catch, and finally blocks. It also indicates which classes its uses from the io.package.

Use input and output to make an echo machine:

Allow the input-output cycle to shut itself off at the end-user's prompt.

This example uses the Character constructor overload to get a single character object, then a string, then test whether the string representation of the character itself a representation of an integer.

You can also write a Unicode file from the lines the user types at the console:

Two ways to copy a file to another are using streams and using channels. Streams are part of the standard io package. This program uses the java.io.FileOutputStream.write method ( http://java.sun.com/javase/6/docs/api/java/io/FileOutputStream.html#write%28byte[],%20int,%20int%29 ) to output a buffer of 1024 bytes to the FileOutputStream until there are not more bytes to write (until -1 is returned).

Channels are part of the the nio (new I/O) package. Channels were added for scalability and to support optimized data transfer with a pool of threads, and for channels, which support asynchronous I/O with direct buffers outside the JVM in the host OS, and concurrent access with regional file locking (so multiple users or applications can update separate areas of a single file simultaneously). If you work with databases, this advanced topic might be valuable with large tables. NIO can also take advantage of a memory mapped file outside the JVM, which means the operating system directly uses hard disk space for paging a large file as if it were loaded into RAM.
