I/O Streams

IO

Terms:

How to (techniques for 1.0 and 1.1)

And new with (1.1)

Newest - with 1.5 java.util.Scanner

These streams supersede the byte streams for all textual I/O

Subs:

The following are used for serialization:

One of the early inventions of the UNIX operating system was the pipe. By unifying disparate ways of communicating into a single metaphor, UNIX paved the way for a whole series of related inventions, culminating in the abstraction known as streams. [this info from Java in 21 days]

A stream is a path of communication between the source of some information and its destination. (Streams can be chained...info flows from one to the other to the other). Overview of IO streams (old but nice hierarchy diagram) and newer tutorial version ("No matter how they work internally, all streams present the same simple model to programs that use them: a stream is a sequence of data.")

A pipe is an uninterpreted stream of bytes that can be used for communicating between programs or for reading and writing to peripheral devices and files. (Consider the stream as being piped to (or from) a source)

This information, an uninterpreted stream of bytes, can come from any "pipe source", the computer's memory, the Internet, etc. In fact, the source and destination of the information are completely arbitrary producers and consumers of bytes. Therein lies the power of the abstraction; you don't need to know about the source of the information when reading from a stream or the destination when writing to one.

General-purpose methods accept a stream argument to specify that source or destination. Arbitrary processors (or filters) of data have two stream arguments - read first, write to second. The processors have no clue about the streams - stream could be to files, could be to sockets, ...

UNIX users and users familiar with command lines have used a type of I/O commonly known as standard I/O.

System Class (in java.lang)

Java gives access to standard I/O via the system class. Specifically, the three files are implemented in Instance Variables there.

Stdin

implements stdin as an instanceof the InputStream class (java.io.InputStream). The "standard" input stream. This stream is already open and ready to supply input data. Typically this stream corresponds to keyboard input or another input source specified by the host environment or user.
With System.in, you have access to the read() and skip(long n) methods.

read() allows you to read one byte of input.
skip(long n) skips over n bytes of the input

Stdout

implements Stdout as a PrintStream. The "standard" output stream. This stream is already open and ready to accept output data. Typically this stream corresponds to display output or another output destination specified by the host environment or user.
You can use the print() and println() methods supplying any of the Java base types as arguments. For simple stand-alone Java applications, a typical way to write a line of output data is:
System.out.println(data)

Stderr

implements stderr in the same was as stdout. The "standard" error output stream. This stream is already open and ready to accept output data. As with System.out, you have access to the PrintStream methods. By convention, this output stream is used to display error messages or other information that should come to the immediate attention of a user even if the principal output stream, the value of the variable out, has been redirected to a file or other destination that is typically not continuously monitored.

Here is an example that works similarly to the UNIX cat or DOS type utility:

Common I/O classes - the tutorial and particularly: Character Streams and Byte Streams

Creating File Objects

Before we can perform I/O on a file, we need to have it!

The File class provides several utilities for dealing with files and obtaining basic information about these files.
Java In a Nutshell
Files and Directories

To create a file, you can use any of three constructors:

The constructor you use will depend on the other file objects you need to access. For example, if you use only one file in your application, the first is easiest. Several files from a common directory indicates the other two.

See API for methods (e.g. canRead(), exists(), list(), length(), isFile(), isDirectory(), ...)

A sample stand-alone application to display basic file information on files passed in as command-line arguments:

import java.io.*;
/*
 * fileInfo
 * A simple File object test program.
 */
class fileInfo {
	public static void main(String args[ ]) throws IOException {
		File fileToCheck;
		if (args.length > 0) {
			for (int i = 0; i < args.length; i++) {
				fileToCheck = new File(args[i]);
				info(fileToCheck);
			}
		}
		else {
			System.out.println("No file given.");
		}
	}


	public static void info (File f) throws IOException {
		System.out.println("Name: " + f.getName( ));
		System.out.println("Path: " + f.getPath( ));
		if (f.exists()) {
			System.out.print("File exists");
			System.out.print((f.canRead() ? " and is Readable":""));
			System.out.print((f.canWrite()? " and is Writable":""));
			System.out.println(".");
			System.out.println("File is "+f.length( )+" bytes.");
		}
		else {
			System.out.println("File does not exist.");
		}
	}
}

Input Streams

InputStream and OutputStream are abstract classes that define methods for reading and writing bytes. Their subclasses allow bytes to be read from and written to a variety of sources and sinks.

FileInputStream and FileOutputStream read from and write to files. ByteArrayInputStream and ByteArrayOutputStream read from and write to an array of bytes in memory. PipedInputStream reads bytes from a PipedOutputStream (and vice versa with writes) These classes work together to implement a "pipe" for communication between threads.

Java In a Nutshell: Input and Output Streams interesting ... java.util.zip

FileInputStreams

FileInputStreams typically represent text files accessed in sequential order, byte by byte. With FileInputStreams, you can choose to access one byte, several bytes or the entire file.

To open, you give a String or a File object to the constructor

or

Reading a FileInputStream

When finished with a file, close it explicitly (or will close with garbage collect) Displaying a File (also
FileViewer and FileLister in Java in a Nutshell 1) (old code)

If the security settings allow for retrieval of files, you can display the contents in a TextArea object.

FilterInputStream

FilterInputStream and FilterOutputStream are special - they filter input and output bytes. When a FilterInputStream is created, an InputStream is specified for it to filter. FilterInputStream and FilterOutputStream do not perform any filtering themselves; this is done by their subclasses. Consider one of its subclasses: DataInputStream

DataInputStreams

DataInputStreams behave much like FileInputStreams. Data streams can directly read any of the native types (int, char, etc). Generally you use a DataInputStream with binary data files.

see hierarchy

For opening an closing, use the same methods you do for FileInputStreams

When accessing a file as a DataInput Stream, you can use the same methods (eg. read() ) available to FileInputStream objects, but you also have access to methods designed specifically to read various data types

Each method will read one object of the type requested.

To read a short, for example

For the String readLine() method, you signal termination of the string with any of \n, \r, \r\n, or EOF.

Not any more....deprecated: the most noticable difference from version 1.0 is that the method readLine() from DataInputStream is no longer there.

It is now available in BufferedReader - Readers are for reading characters rather than bytes. More about this later.

URL Input Streams

Java provides you with the ability to use URLs as a means of accessing objects across a network. We implicitly use a URL object when we access sounds and images using the getDocumentBase() method for applets

However, you can use a direct URL if you want:

Opening an Input Stream

One can open an input stream off of an appropriate URL. For example, you can include a data file for one of your applets:

Now you can use istream to read information like you do with a FileInputStream object

URL is at java.net.URL

Also:

openStream() is a method in URL that opens a connection to this URL and returns an InputStream for reading from that connection.

You can also explicitly connect to the URL (so you could test - openConnection throws an IOException - as do most I/O streams). openConnection() returns a URLConnection object that represents a connection to the remote object referred to by this URL.

Always remember that users may have their browsers protections set to not allow applets to access files.

Also, always remember to do I/O in try/catch blocks since most I/O methods throw exceptions.

InputStream, FilterInputStream, OutputStream, and FilterOutpuStream are all abstract classes (in API). They provide the methods for the specific classes used (BufferedInputStream, DataInputStream, LineNumberInputStream, PushbackInputStream, BufferedOutputStream, DataOutputStream, PrintStream) (see page 383 "Java in 21 Days")


I/O Streams: appended 1.1

Java version 1.1 has some changes in the I/O. Here is more info.
the IO API again

Most noticable are the following:

Reader is the superclass of all character input streams and
Writer is the superclass of all character output streams.
These streams supersede the byte streams for all textual I/O

Subs:

The following are used for serialization:

the most noticable difference from version 1.0 is that the method readLine() from DataInputStream is no longer there.

It is now available in BufferedReader

java.io.Reader
Abstract class for reading character streams. The only methods that a subclass must implement are read(char[], int, int) and close(). Most subclasses, however, will override some of the methods defined in order to provide higher efficiency, additional functionality or both.

methods:

SubClasses:

BufferedReader: Reads text from a character- input stream, buffering characters so as to provide for the efficient reading of characters, arrays and lines. The buffer size may be specified or the default size used.

In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders.

For example:
InputStreamReader is a bridge fom byte streams to character streams: It reads bytes and translates them into characters according to a specified character encoding. The encoding that is uses may be specified by name, or the platform's default encoding may be accepted.

Each invocation of one of an InputStreamReader's read() methods may cause one or more bytes to be read from the underlying byte-input stream. For top efficiency, consider wrapping an InputStreamReader within a BufferedReader:

BufferedReader in = new BufferedReader(new InputStreamReader (System.in));

Objects are serialized with the ObjectOutputStream and they are deserialized with the ObjectInputStream. Both of these classes are part of the java.io package, and they function, in many ways, like DataOutputStream and DataInputStream because they define the same methods for writing and reading binary representations of Java primitive types to and from streams. What ObjectOutputStream and ObjectInputStream add, however, is the ability to write and read non-primitive object and array values to and from a stream. See serialization notes.