In many ways this book is a prequel to my previous book, Java Network Programming (O’Reilly & Associates). When writing that book, I more or less assumed that readers were familiar with basic input and output in Java™—that they knew how to use input streams and output streams, convert bytes to characters, connect filter streams to each other, and so forth.
However, after that book was published, I began to notice that a lot
of the questions I got from readers of the book and students in my
classes weren’t so much about network programming itself as
they were about input and output (I/O in programmer vernacular). When
Java 1.1 was released with a vastly expanded
java.io package and many new I/O classes spread
out across the rest of the class library, it became obvious that a
book that specifically addressed I/O was required. This is that book.
Java I/O endeavors to show you how to really use Java’s I/O classes, allowing you to quickly and easily write programs that accomplish many common tasks. Some of these include:
Reading and writing files
Communicating over network connections
Interpreting a wide variety of formats for integer and floating-point numbers
Passing data between threads
Encrypting and decrypting data
Calculating digital signatures for streams
Compressing and decompressing data
Writing objects to streams
Copying, moving, renaming, and getting information about files and directories
Letting users choose files from a GUI interface
Reading and writing non-English text in a variety of character sets
Formatting integer and floating-point numbers as strings
Talking directly to modems and other serial port devices
Talking directly to printers and other parallel port devices
Java is the first language to provide a cross-platform I/O library that is powerful enough to handle all these diverse tasks. Java I/O is the first book to fully expose the power and sophistication of this library.
Java is the first programming language with a modern, object-oriented approach to input and output. Java’s I/O model is more powerful and more suited to real-world tasks than any other major language used today. Surprisingly, however, I/O in Java has a bad reputation. It is widely believed (falsely) that Java I/O can’t handle basic tasks that are easily accomplished in other languages like C, C++, and Pascal. In particular, it is commonly said that:
I/O is too complex for introductory students; or, more specifically, there’s no good way to read a number from the console.
Java can’t handle basic formatting tasks like printing π with three decimal digits of precision.
This book will show you that not only can Java handle these two tasks with relative ease and grace; it can do anything C and C++ can do, and a whole lot more. Java’s I/O capabilities not only match those of classic languages like C and Pascal, they vastly surpass them.
The most common complaint about Java I/O among students, teachers,
authors of textbooks, and posters to
comp.lang.java is that there’s no simple
way to read a number from the console
System.in). Many otherwise
excellent introductory Java books repeat this canard. Some textbooks
go to great lengths to reproduce the behavior they’re
accustomed to from C or Pascal, apparently so teachers don’t
have to significantly rewrite the tired Pascal exercises
they’ve been using for the last 20 years. However, new books
that aren’t committed to the old ways of doing things generally
use command-line arguments for basic exercises, then rapidly
introduce the graphical user interfaces any real program is going to
use anyway. Apple wisely abandoned the command-line interface back in
1984, and the rest of the world is slowly catching up. Although
System.out are certainly convenient for teaching
and debugging, in 1999 no completed, cross-platform program should
even assume the existence of a console for either input or output.
The second common complaint about Java I/O is that it can’t
handle formatted output; that is, that there’s no equivalent of
printf() in Java. In a very narrow sense, this is
true because Java does not support the variable length argument lists
a function like
printf() requires. Nonetheless, a
number of misguided souls (your author not least among them) have at
one time or another embarked on futile efforts to reproduce
printf() in Java. This may have been necessary in
Java 1.0, but as of Java 1.1, it’s no longer needed. The
java.text package, discussed in Chapter 16, provides complete support for formatting
numbers. Furthermore, the
java.text package goes
way beyond the limited capabilities of
It supports not only different precisions and widths, but also
internationalization, currency formats, percentages, grouping
symbols, and a lot more. It can easily be extended to handle Roman
numerals, scientific or exponential notation, or any other number
format you may require.
The underlying flaw in most people’s analysis of Java I/O is that they’ve confused input and output with the formatting and interpreting of data. Java is the first major language to cleanly separate the classes that read and write bytes (primarily, various kinds of input streams and output streams) from the classes that interpret this data. You often need to format strings without necessarily writing them on the console. You may also need to write large chunks of data without worrying about what they represent. Traditional languages that connect formatting and interpretation to I/O and hard-wire a few specific formats are extremely difficult to extend to other formats. In essence, you have to give up and start from scratch every time you want to process a new format.
only really works well on Unix (where, not coincidentally, C was
invented). On other platforms, the underlying assumption that every
target may be treated as a file fails, and these standard library
functions must be replaced by other functions from the host API.
Java’s clean separation between formatting and I/O allows you to create new formatting classes without throwing away the I/O classes, and to write new I/O classes while still using the old formatting classes. Formatting and interpreting strings are fundamentally different operations from moving bytes from one device to another. Java is the first major language to recognize and take advantage of this.
 MacOS X will reportedly add a real command-line shell to the Mac for the first time ever. Mainly, this is because MacOS X has Unix at its heart. However, Apple at least has the good taste to hide the shell so it won’t confuse end users and tempt developers away from the righteous path of graphical user interfaces.