(This page has no text content)
Java I/O Elliotte Rusty Harold Publisher: O'Reilly First Edition March 1999 ISBN: 1-56592-485-1, 596 pages All of Java's Input/Output (I/O) facilities are based on streams, which provide simple ways to read and write data of different types. Java™ I/O tells you all you need to know about the four main categories of streams and uncovers less-known features to help make your I/O operations more efficient. Plus, it shows you how to control number formatting, use characters aside from the standard ASCII character set, and get a head start on writing truly multilingual software
Table of Contents Preface ..................................................... Correcting Misconceptions ....................................... Organization of the Book ........................................ Who You Are ................................................ Versions ................................................... Security Issues ............................................... Conventions Used in This Book .................................... Request for Comments .......................................... Acknowledgments ............................................. 1 1 3 8 8 9 9 11 12 I: Basic I/O .................................................. 13 1. Introducing I/O .............................................. 1.1 What Is a Stream? ........................................... 1.2 Numeric Data ............................................. 1.3 Character Data ............................................. 1.4 Readers and Writers ......................................... 1.5 The Ubiquitous IOException ................................... 1.6 The Console: System.out, System.in, and System.err .................... 1.7 Security Checks on I/O ....................................... 14 14 17 20 24 25 26 32 2. Output Streams ............................................. 2.1 The OutputStream Class ...................................... 2.2 Writing Bytes to Output Streams ................................. 2.3 Writing Arrays of Bytes ....................................... 2.4 Flushing and Closing Output Streams .............................. 2.5 Subclassing OutputStream ..................................... 2.6 A Graphical User Interface for Output Streams ........................ 34 34 34 36 37 38 39 3. Input Streams ............................................... 3.1 The InputStream Class ........................................ 3.2 The read( ) Method .......................................... 3.3 Reading Chunks of Data from a Stream ............................ 3.4 Counting the Available Bytes ................................... 3.5 Skipping Bytes ............................................. 3.6 Closing Input Streams ........................................ 3.7 Marking and Resetting ........................................ 3.8 Subclassing InputStream ...................................... 3.9 An Efficient Stream Copier .................................... 42 42 42 44 45 46 46 47 47 48 II: Data Sources ............................................... 50 4. File Streams ................................................ 4.1 Reading Files .............................................. 4.2 Writing Files .............................................. 4.3 File Viewer, Part 1 .......................................... 51 51 53 56 5. Network Streams ............................................ 5.1 URLs ................................................... 5.2 URL Connections ........................................... 5.3 Sockets .................................................. 5.4 Server Sockets ............................................. 5.5 URLViewer ............................................... 60 60 62 65 68 71
III: Filter Streams ............................................. 6. Filter Streams ............................................... 74 6.1 The Filter Stream Classes ...................................... 6.2 The Filter Stream Subclasses ................................... 6.3 Buffered Streams ........................................... 6.4 PushbackInputStream ........................................ 6.5 Print Streams .............................................. 6.6 Multitarget Output Streams ..................................... 6.7 File Viewer, Part 2 .......................................... 75 75 80 81 83 84 85 89 7. Data Streams ............................................... 7.1 The Data Stream Classes ...................................... 7.2 Reading and Writing Integers ................................... 7.3 Reading and Writing Floating-Point Numbers ........................ 7.4 Reading and Writing Booleans .................................. 7.5 Reading Byte Arrays ......................................... 7.6 Reading and Writing Text ..................................... 7.7 Miscellaneous Methods ....................................... 7.8 Reading and Writing Little-Endian Numbers ......................... 7.9 Thread Safety ............................................. 7.10 File Viewer, Part 3 ......................................... 96 96 98 103 106 106 107 111 111 123 124 8. Streams in Memory ........................................... 8.1 Sequence Input Streams ....................................... 8.2 Byte Array Streams .......................................... 8.3 Communicating Between Threads with Piped Streams ................... 131 131 132 135 9. Compressing Streams ......................................... 9.1 Inflaters and Deflaters ........................................ 9.2 Compressing and Decompressing Streams ........................... 9.3 Working with Zip Files ....................................... 9.4 Checksums ............................................... 9.5 JAR Files ................................................ 9.6 File Viewer, Part 4 .......................................... 140 140 152 159 172 176 189 10. Cryptographic Streams ....................................... 10.1 Hash Function Basics ....................................... 10.2 The MessageDigest Class ..................................... 10.3 Digest Streams ............................................ 10.4 Encryption Basics .......................................... 10.5 The Cipher Class .......................................... 10.6 Cipher Streams ............................................ 10.7 File Viewer, Part 5 ......................................... 193 193 195 203 209 212 225 231 IV: Advanced and Miscellaneous Topics .............................. 236 11. Object Serialization .......................................... 11.1 Reading and Writing Objects ................................... 11.2 Object Streams ............................................ 11.3 How Object Serialization Works ................................ 11.4 Performa 11.5 The Serializable Interface ..................................... nce ............................................. 11.6 The ObjectInput and ObjectOutput Interfaces ........................ 11.7 Versioning ............................................... 11.8 Customizing the Serialization Format ............................. 11.9 Resolving Classes .......................................... 11.10 Resolving Objects ......................................... 237 237 238 239 241 241 247 249 251 260 261
11.11 Validation .............................................. 11.12 Sealed Objects ........................................... 261 263 12. Working with Files .......................................... 12.1 Understanding Files ......................................... 12.2 Directories and Paths ........................................ 12.3 The File Class ............................................ 12.4 Filename Filters ........................................... 12.5 File Filters ............................................... 12.6 File Descriptors ........................................... 12.7 Random-Access Files ....................................... 12.8 General Techniques for Cross-Platform File Access Code ................ 267 267 274 280 299 300 301 302 304 13. File Dialogs and Choosers ...................................... 13.1 File Dialogs .............................................. 13.2 JfileChooser .............................................. 13.3 File Viewer, Part 6 ......................................... 306 306 313 331 14. Multilingual Character Sets and Unicode ........................... 14.1 Unicode ................................................ 14.2 Displaying Unicode Text ..................................... 14.3 Unicode Escapes ........................................... 14.4 UTF-8 ................................................. 14.5 The char Data Type ......................................... 14.6 Other Encodings ........................................... 14.7 Converting Between Byte Arrays and Strings ........................ 337 337 338 345 346 348 356 357 15. Readers and Writers ......................................... 15.1 The java.io.Writer Class ...................................... 15.2 The OutputStreamWriter Class ................................. 15.3 The java.io.Reader Class ..................................... 15.4 The InputStreamReader Class .................................. 15.5 Character Array Readers and Writers ............................. 15.6 String Readers and Writers .................................... 15.7 Reading and Writing Files .................................... 15.8 Buffered Readers and Writers .................................. 15.9 Print Writers ............................................. 15.10 Piped Readers and Writers ................................... 15.11 Filtered Readers and Writers .................................. 15.12 File Viewer Finis .......................................... 360 360 361 363 365 366 369 372 374 378 380 381 386 16. Formatted I/O with java.text .................................... 16.1 The Old Way ............................................. 16.2 Choosing a Locale .......................................... 16.3 Number Formats ........................................... 16.4 Specifying Width with FieldPosition .............................. 16.5 Parsing Input ............................................. 16.6 Decimal Formats .......................................... 16.7 An Exponential Number Format ................................ 395 395 397 400 408 412 414 423 17. The Java Communications API .................................. 17.1 The Architecture of the Java Communications API .................... 17.2 Identifying Ports ........................................... 17.3 Communicating with a Device on a Port ........................... 17.4 Serial Ports .............................................. 17.5 Parallel Ports ............................................. 429 429 430 437 443 452
V: Appendixes ................................................ 458 A. Additional Resources ......................................... A.1 Digital Think ............................................. A.2 Design Patterns ............................................ A.3 The java.io Package ......................................... A.4 Network Programming ....................................... A.5 Data Compression .......................................... A.6 Encryption and Related Technology .............................. A.7 Object Serialization ......................................... A.8 International Character Sets and Unicode ........................... A.9 Java Communications API ..................................... A.10 Updates and Breaking News ................................... 459 459 459 460 460 461 461 462 462 463 463 B. Character Sets .............................................. 465 Colophon .................................................... 472
Dedication To Lynn, the best aunt a boy could ask for.
Java I/O 1 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.
Java I/O 2 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 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.
Java I/O 3 operations from moving bytes from one device to another. Java is the first major language to recognize and take advantage of this. Organization of the Book This book has 17 chapters that are divided into four parts, plus two appendixes. Part I: Basic I/O Chapter 1 Chapter 1 introduces the basic architecture and design of the java.io package, including the reader/stream dichotomy. Some basic preliminaries about the int, byte, and char data types are discussed. The IOException thrown by many I/O methods is introduced. The console is introduced, along with some stern warnings about its proper use. Finally, I offer a cautionary message about how the security manager can interfere with most kinds of I/O, sometimes in unexpected ways. Chapter 2 Chapter 2 teaches you the basic methods of the java.io.OutputStream class you need to write data onto any output stream. You'll learn about the three overloaded versions of write(), as well as flush() and close(). You'll see several examples, including a simple subclass of OutputStream that acts like /dev/null and a TextArea component that gets its data from an output stream. Chapter 3 The third chapter introduces the basic methods of the java.io.InputStream class you need to read data from a variety of sources. You'll learn about the three overloaded variants of the read() method and when to use each. You'll see how to skip over data and check how much data is available, as well as how to place a bookmark in an input stream, then reset back to that point. You'll learn how and why to close input streams. This will all be drawn together with a StreamCopier program that copies data read from an input stream onto an output stream. This program will be used repeatedly over the next several chapters. Part II: Data Sources Chapter 4 The majority of I/O involves reading or writing files. Chapter 4 introduces the FileInputStream and FileOutputStream classes, concrete subclasses of InputStream and OutputStream that let you read and write files. These classes have all the usual methods of their superclasses, such as read(), write(), available(), flush(), and so on. Also in this chapter, development of a File Viewer program commences. You'll see how to inspect the raw bytes in a file in both decimal and hexadecimal format. This example will be progressively expanded throughout the rest of the book.
Java I/O 4 Chapter 5 From its first days, Java has always had the network in mind, more so than any other common programming language. Java is the first programming language to provide as much support for network I/O as it does for file I/O, perhaps even more. Chapter 5 introduces Java's URL, URLConnection, Socket, and ServerSocket classes, all fertile sources of streams. Typically the exact type of the stream used by a network connection is hidden inside the undocumented sun classes. Thus network I/O relies primarily on the basic InputStream and OutputStream methods. Examples in this chapter include several simple web and email clients. Part III: Filter Streams Chapter 6 Chapter 6 introduces filter streams. Filter input streams read data from a preexisting input stream like a FileInputStream, and have an opportunity to work with or change the data before it is delivered to the client program. Filter output streams write data to a preexisting output stream such as a FileOutputStream, and have an opportunity to work with or change the data before it is written onto the underlying stream. Multiple filters can be chained onto a single underlying stream to provide the functionality offered by each filter. Filters streams are used for encryption, compression, translation, buffering, and much more. At the end of this chapter, the File Viewer program is redesigned around filter streams to make it more extensible. Chapter 7 Chapter 7 introduces data streams, which are useful for writing strings, integers, floating-point numbers, and other data that's commonly presented at a level higher than mere bytes. The DataInputStream and DataOutputStream classes read and write the primitive Java data types (boolean, int, double, etc.) and strings in a particular, well-defined, platform-independent format. Since DataInputStream and DataOutputStream use the same formats, they're complementary. What a data output stream writes, a data input stream can read, and vice versa. These classes are especially useful when you need to move data between platforms that may use different native formats for integers or floating-point numbers. Along the way, you'll develop classes to read and write little-endian numbers, and you'll extend the File Viewer program to handle big- and little-endian integers and floating-point numbers of varying widths. Chapter 8 Chapter 8 shows you how streams can move data from one part of a running Java program to another. There are three main ways to do this. Sequence input streams chain several input streams together so that they appear as a single stream. Byte array streams allow output to be stored in byte arrays and input to be read from byte arrays. Finally, piped input and output streams allow output from one thread to become input for another thread.
Java I/O 5 Chapter 9 Chapter 9 explores the java.util.zip and java.util.jar packages. These packages contain assorted classes that read and write data in zip, gzip, and inflate/deflate formats. Java uses these classes to read and write JAR archives and to display PNG images. However, the java.util.zip classes are more general than that, and can be used for general-purpose compression and decompression. Among other things, they make it trivial to write a simple compressor or decompressor program, and several will be demonstrated. In the final example, support for compressed files is added to the File Viewer program. Chapter 10 The Java core API contains two cryptography-related filter streams in the java.security package, DigestInputStream and DigestOutputStream. There are two more in the javax.crypto package, CipherInputStream and CipherOutputStream, available in the Java Cryptography Extension™ (JCE for short). Chapter 10 shows you how to use these classes to encrypt and decrypt data using a variety of algorithms, including DES and Blowfish. You'll also learn how to calculate message digests for streams that can be used for digital signatures. In the final example, support for encrypted files is added to the File Viewer program. Part IV: Advanced and Miscellaneous Topics Chapter 11 The first 10 chapters showed you how to read and write various primitive data types to many different kinds of streams. Chapter 11 shows you how to write everything else. Object serialization, first used in the context of remote method invocation (RMI) and later for JavaBeans™, lets you read and write almost arbitrary objects onto a stream. The ObjectOutputStream class provides a writeObject() method you can use to write a Java object onto a stream. The ObjectInputStream class has a readObject() method you can use to read an object from a stream. In this chapter, you'll learn how to use these two classes to read and write objects, as well as how to customize the format used for serialization. Chapter 12 Chapter 12 shows you how to perform operations on files other than simply reading or writing them. Files can be moved, deleted, renamed, copied, and manipulated without respect to their contents. Files are also often associated with meta-information that's not strictly part of the contents of the file, such as the time the file was created, the icon for the file, or the permissions that determine which users can read or write to the file. The java.io.File class attempts to provide a platform-independent abstraction for common file operations and meta-information. Unfortunately, this class really shows its Unix roots. It works fine on Unix, reasonably well on Windows—with a few caveats—and fails miserably on the Macintosh. File manipulation is thus one of the real bugbears of cross-platform Java programming. Therefore, this chapter shows you
Java I/O 6 not only how to use the File class, but also the precautions you need to take to make your file code portable across all major platforms that support Java. Chapter 13 Filenames are problematic, even if you don't have to worry about cross-platform idiosyncrasies. Users forget filenames, mistype them, can't remember the exact path to files they need, and more. The proper way to ask a user to choose a file is to show them a list of the files and let them pick one. Most graphical user interfaces provide standard graphical widgets for selecting a file. In Java, the platform's native file selector widget is exposed through the java.awt.FileDialog class. Like many native peer-based classes, however, FileDialog doesn't behave the same or provide the same services on all platforms. Therefore, the Java Foundation Classes™ 1.1 (Swing) provide a pure Java implementation of a file dialog, the javax.swing.JFileChooser class. Chapter 13 shows you how to use both these classes to provide a GUI file selection interface. In the final example, you'll add a Swing-based GUI to the File Viewer program. Chapter 14 We live on a planet where many languages are spoken, yet most programming languages still operate under the assumption that everything you need to say can be expressed in English. Java is starting to change that by adopting the multinational Unicode as its native character set. All Java chars and strings are given in Unicode. However, since there's also a lot of non-Unicode legacy text in the world, in a dizzying array of encodings, Java also provides the classes you need to read and write this text in these encodings as well. Chapter 14 introduces you to the multitude of character sets used around the world, and develops a simple applet to test which ones your browser/VM combination supports. Chapter 15 A language that supports international text must separate the reading and writing of raw bytes from the reading and writing of characters, since in an international system they are no longer the same thing. Classes that read characters must be able to parse a variety of character encodings, not just ASCII, and translate them into the language's native character set. Classes that write characters must be able to translate the language's native character set into a variety of formats and write those. In Java, this task is performed by the Reader and Writer classes. Chapter 15 shows you how to use these classes, and adds support for multilingual text to the File Viewer program. Chapter 16 Java 1.0 did not provide classes for specifying the width, precision, and alignment of numeric strings. Java 1.1 and later make these available as subclasses of java.text.NumberFormat. As well as handling the traditional formatting achieved by languages like C and Fortran, NumberFormat also internationalizes numbers with different character sets, thousands separators, decimal points, and digit characters. Chapter 16 shows you how to use this class and its subclasses for traditional tasks, like
Java I/O 7 lining up the decimal points in a table of prices, and nontraditional tasks, like formatting numbers in Egyptian Arabic. Chapter 17 Chapter 17 introduces the Java Communications API, a standard extension available for Java 1.1 and later that allows Java applications and trusted applets to send and receive data to and from the serial and parallel ports of the host computer. The Java Communications API allows your programs to communicate with essentially any device connected to a serial or parallel port, like a printer, a scanner, a modem, a tape backup unit, and so on. Chapter 1 through Chapter 3 provide the basic background you'll need to do any sort of work with I/O in Java. After that, you should feel free to jump around as your interests take you. There are, however, some interdependencies between specific chapters. Figure P.1 should allow you to map out possible paths through the book. Figure P.1. Chapter prerequisites A few examples in later chapters depend on material from earlier chapters—for instance, many examples use the FileInputStream class discussed in Chapter 4—but they should not be difficult to understand in the large.
Java I/O 8 Who You Are This book assumes you have a basic familiarity with Java. You should be thoroughly familiar with the syntax of the language. You should be comfortable with object-oriented programming, including terminology like instances, objects, and classes, and you should know the difference between these terms. You should know what a reference is and what that means for passing arguments to and returning values from methods. You should have written simple applications and applets. For the most part, I try to keep the examples relatively straightforward so that they require a minimum of understanding of other parts of the class library outside the I/O classes. This may lead some to deride these as "toy examples." However, I find that such examples are far more conducive to understanding and learning than full-blown sophisticated programs that fill page after page with graphical user interface code just to demonstrate a two-line point about I/O. Occasionally, however, a graphical example is simply too tempting to ignore, as in the StreamedTextArea class shown in Chapter 2 or the File Viewer application developed throughout most of the book. I will try to keep the AWT material to a minimum, but a familiarity with 1.1 AWT basics will be assumed. When you encounter a topic that requires a deeper understanding for I/O than is customary— for instance, the exact nature of strings—I'll cover that topic as well, at least briefly. However, this is not a language tutorial, and the emphasis will always be on the I/O-specific features. Versions In many ways, this book was inspired by the wealth of new I/O functionality included in Java 1.1. I/O in Java 1.0 is overall much simpler, though also much less powerful. For instance, there are no Reader and Writer classes in Java 1.0. However, there's also no reliable way to read pure Unicode text. Furthermore, Java 1.1 added many new classes to the library for performing a variety of I/O-related tasks like compression, encryption, digital signatures, object serialization, encoding conversion, and much more. Therefore, this book assumes at least Java 1.1. For the most part, Java 1.0 has been relegated to developing applets that run inside web browsers. Because the applet security manager severely restricts the I/O an untrusted applet can undertake, most applets do not make heavy use of I/O, and thus it should not be a major concern. Java 2's I/O classes are mostly identical to those in Java 1.1, with one noticeable exception. Java 2 does a much better (though still imperfect) job of abstracting out platform-dependent filesystem idiosyncrasies than does Java 1.1. Some (though not all) of these improvements are also available to Java 1.1 programmers working with Swing. I'll discuss both the Java 1.1 and Java 2 approaches to the filesystem in Chapter 12. In any case, when I discuss a method, class or interface that's only available in Java 2, its signature will be suffixed with a comment indicating that. For example: public interface Replaceable extends Serializable // Java 2
Java I/O 9 Security Issues I don't know if there's one most frequently asked question about Java Network Programming, but there's definitely a most frequent answer, and it applies to this book too. My mistake in Java Network Programming was hiding that answer in the back of a chapter most people didn't read. Since that very same answer should answer an equal number of questions from readers of this book, I want to get it out of the way right up front: Java's security manager prevents almost all the examples and methods discussed in this book from working in an applet. This book focuses very much on applications. There is very little that can be done with I/O from an untrusted applet without running afoul of the security manager. The problem may not always be obvious—not all web browsers properly report security exceptions—but it is there. There are some exceptions. Byte array streams and piped streams work without limitation in applets. Network connections can be made back to the host from whence the applet came (and only to that host). System.in and System.out may be accessible from some, though not all, web browsers. And in Java 2 and later, there are ways to relax the restrictions on applets so they get limited access to the filesystem or unlimited access to the network. However, these are exceptions, not the rule. If you can make an applet work when run as a standalone application and you cannot get it to work inside a web browser, the problem is almost certainly a conflict with the browser's security manager. Conventions Used in This Book Italic is used for: • Filenames (readme.txt ) • Host and domain names (http://www.oreilly.com/) • URLs (http://metalab.unc.edu/javafaq/) Constant width is used for: • Code examples and fragments • Class, variable, and method names, and Java keywords used within the text Significant code fragments and complete programs are generally placed in a separate paragraph like this: InputStream in = new FileInputStream("/etc/mailcap"); When code is presented as fragments rather than complete programs, the existence of the appropriate import statements should be inferred. For example, in the previous code fragment you may assume that java.io.InputStream and java.io.FileInputStream were imported.
Java I/O 10 Some examples intermix user input with program output. In these cases, the user input will be displayed in bold, but otherwise in the same monospaced font, as in this example from Chapter 17: D:\JAVA\16>java PortTyper COM2 at&f at&f OK atdt 321-1444 Most of the code examples in this book are optimized for legibility rather than speed. For instance, consider this getIcon() method from Chapter 13: public Icon getIcon(File f) { if (f.getName().endsWith(".zip")) return zipIcon; if (f.getName().endsWith(".gz")) return gzipIcon; if (f.getName().endsWith(".dfl")) return deflateIcon; return null; } I invoke the f.getName() method three times, when once would do: public Icon getIcon(File f) { String name = f.getName(); if (name.endsWith(".zip")) return zipIcon; if (name.endsWith(".gz")) return gzipIcon; if (name.endsWith(".dfl")) return deflateIcon; return null; } However, this seemed slightly less obvious than the first example. Therefore, I chose the marginally slower form. Other, still less obvious optimizations are also possible, but would only make the code even more obscure. For example: public Icon getIcon(File f) { String name = f.getName(); String lastDot = name.lastIndexOf('.'); if (lastDot != -1) { String extension = name.substring(lastDot+1); if (extension.equals("zip")) return zipIcon; if (extension.equals("gz")) return gzipIcon; if (extension.equals("dfl")) return deflateIcon; } return null; } I might resort to this form if profiling proved that this method was a performance bottleneck in my application, and this revised method was genuinely faster, but I certainly wouldn't use it in my first pass at the problem. In general, I only optimize for speed when similar code seems likely to be a performance bottleneck in situations where it's likely to be used, or when optimizing can be done without negatively affecting the legibility of the code.
Java I/O 11 Finally, although many of the examples are toys unlikely to be reused, a few of the classes I develop have real value. Please feel free to reuse them or any parts of them in your own code; no special permission is required. Such classes are placed somewhere in the com.macfaq package, generally mirroring the java package hierarchy. For instance, Chapter 2's NullOutputStream class is in the com.macfaq.io package; its StreamedTextArea class is in the com.macfaq.awt package. When working with these classes, don't forget that the compiled .class files must reside in directories matching their package structure inside your class path and that you'll have to import them in your own classes before you can use them.[2] The web page includes a JAR file that can be installed in your class path. Furthermore, classes not in the default package with main() methods are generally run by passing in the full package-qualified name. For example: D:\JAVA\ioexamples\04>java com.macfaq.io.FileCopier oldfile newfile Request for Comments I enjoy hearing from readers, whether with general comments about how this could be a better book, specific corrections, or other topics you would like to see covered. You can reach me by sending email to elharo@metalab.unc.edu. Please realize, however, that I receive several hundred pieces of email a day and cannot personally respond to each one. I'm especially interested in hearing about mistakes. If you find one, I'll post it on my web page for this book at http://metalab.unc.edu/javafaq/books/javaio/ and on the O'Reilly web site at http://www.oreilly.com/catalog/javaio/. Before reporting errors, please check one of those pages to see if I already know about it and have posted a fix. Let me also preempt a couple of non-errors that are often mistakenly reported. First, the signatures given in this book don't necessarily match the signatures given in the javadoc documentation. I often change method argument names to make them clearer. For instance, Sun documents the write() method in java.io.OutputStream like this: public void write(byte b[]) throws IOException public void write(byte b[], int off, int len) throws IOException I've rewritten that in this more intelligible form: public void write(byte[] data) throws IOException public void write(byte[] data, int offset, int length) throws IOException These are exactly equivalent, however. Method argument names are purely formal and have no effect on client programmer's code that invokes these methods. I could have rewritten them in Latin or Tuvan without really changing anything. The only difference is in their intelligibility to the reader. 2 See "The Name Space: Packages, Classes, and Members" in the second edition of David Flanagan's Java in a Nutshell (O'Reilly & Associates, 1997).
Java I/O 12 Acknowledgments Many people were involved in the production of this book. All these people deserve much thanks and credit. My editor, Mike Loukides, got this book rolling and provided many helpful comments that substantially improved it. Clairemarie Fisher O'Leary, Chris Maden, and Robert Romano deserve a special commendation for putting in all the extra effort needed for a book that makes free use of Arabic, Cyrillic, Chinese, and other non-Roman scripts. Tim O'Reilly and the whole crew at O'Reilly deserve special thanks for building a publisher that's willing to give a book the time and support it needs to be a good book rather than rushing it out the door to meet an artificial deadline. Many people looked over portions of the manuscript and provided helpful comments. These included Scott Bortman, Bob Eckstein, and Avner Gelb. Bruce Schneier and Jan Luehe both lent their expertise to the cryptography chapter. Ian Darwin was invaluable in handling the details of the Java Communications API. My agent, David Rogelberg, convinced me it was possible to make a living writing books like this rather than working in an office. Finally, I'd like to save my largest thanks for my wife, Beth, without whose support and assistance this book would never have happened.
Java I/O 13 Part I: Basic I/O
Comments 0
Loading comments...
Reply to Comment
Edit Comment