Preface

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

  • Filtering data

  • 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.

Correcting Misconceptions

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.[1] Although System.in and 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 printf(). 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.

Furthermore, C’s printf(), fprintf(), and sprintf() family 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.



[1] 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.

Get Java I/O now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.