Chapter 2, Output Streams Chapter 2 explores the OutputStream class you need in order to write data onto any output stream.. This is all drawn together with a StreamCopier program that c
Trang 1By Elliotte Rusty Harold
Publisher: O'Reilly Pub Date: May 2006 Print ISBN-10: 0-596-52750-0 Print ISBN-13: 978-0-59-652750-1 Pages: 726
Trang 2By Elliotte Rusty Harold
Publisher: O'Reilly Pub Date: May 2006 Print ISBN-10: 0-596-52750-0 Print ISBN-13: 978-0-59-652750-1 Pages: 726
Trang 8most titles (safari.oreilly.com) For more information, contactour corporate/institutional sales department: (800) 998-9938 or
Trang 9errors or omissions, or for damages resulting from the use ofthe information contained herein
ISBN: 0-596-52750-0
[M]
Trang 10updated and expanded to cover the even more impressive I/Ocapabilities introduced in Java 1.4, 5, and 6 The I/O class
libraries in Java are more powerful and interesting than ever,and this book shows you how to take full advantage of them.Techniques you'll learn here include:
Trang 11Transmitting data wirelessly with Bluetooth
Communicating with the outside world from small devicessuch as cell phones and PDAs
Java is the first language to provide a cross-platform I/O librarythat is powerful enough to handle all these diverse tasks Java
is the first programming language with a modern, object-oriented approach to input and output Java's I/O model is morepowerful and more suited to real-world tasks than any other
major language used today Java I/O is the first and still the
only book to fully expose the power and sophistication of thislibrary
Trang 12The first edition of this book was inspired by the wealth of I/Ofunctionality added in Java 1.1, and this edition was motivated
in large part by the new I/O package introduced in Java 1.4.Therefore, this edition assumes you're working with at leastJava 1.4, though most of the basic material will work as far
back as Java 1.1
Java 1.4 introduced a huge amount of new material relevant toI/O The most obvious additions are the java.nio packages thatprovide nonblocking and memory-mapped I/O Chapters 1416
cover these powerful new abilities in depth java.nio also
exposes character set conversion code that's been present inthe JDK since 1.1 but hasn't had a public API before now This
is the primary subject of Chapter 19
Many still-relevant pre-1.4 topics have been added and
expanded as well The ProgressMonitorInputStream is covered herefor the first time Many more details are offered about objectserialization including serialPersistentFields, writeReplace( ),
11) Among other topics, I explain the Pack200 compressionformat and evangelize the increasingly popular technique ofhiding noncode resources like images and data files inside JARfiles
Java 5 continues to build on the basic I/O functionality of Java1.4 and earlier Many new classes and methods from those
versions are covered here including the Flushable and Closable
interfaces Most shockingly, Java 5 finally brings variable-lengthargument lists and the printf family of functions, the lack ofwhich helped inspire the first edition You'll find that these
functions are even more powerful in Java than they are in C andcan handle not only numbers but also dates and several otherobject types
Trang 13interesting new classes including Console and IOError You'll learnabout these right up front in Chapter 1 Java 6 also introducesseveral useful new methods including a much-improved
interface that's only available in Java 5 or 6, its signature will besuffixed with a comment indicating that For example, this
public FileDialog(Dialog parent, String title) // Java 5
There've been many interesting developments outside the coreJDK, too Some of the most exciting developments have
occurred in the world of small devices, both peripherals such asGPS receivers that connect to a host computer and devices such
as Palm Pilots that are themselves increasingly powerful
computers Treatment of both of these has been dramatically
expanded in this edition
For those readers working with serial and parallel port devices,I've upgraded the Java Communications API chapter to version3.0 However, in 2006 more and more devices use faster USB
ports instead Consequently, Chapter 23 covers the new Java
USB API in depth For smaller devices that can't quite run full
Java but need to perform I/O nonetheless, J2ME offers the
Generic Connection Framework (GCF) Chapter 24 covers this
alternative to the traditional I/O framework Finally, Chapter 25
Trang 14buses, the Bluetooth API used for wireless communications with
a variety of peripherals
Finally, the existing content has been rewritten from page 1 tobring it up to date with the latest thinking in Java code and
style as well as to make it clearer, more compact, and moreaccurate For example, exception handling and multithreading ismuch improved in this edition's examples Streams are closedmore reliably Exceptions are thrown rather than caught whereappropriate, and synchronization is avoided throughout I
discusses some basic preliminaries about the int, byte, and
char data types and introduces the IOException thrown by
Trang 15Chapter 2, Output Streams
Chapter 2 explores the OutputStream class you need in order
to write data onto any output stream You'll learn about thethree overloaded versions of write( ) as well as flush( ) and
to place a bookmark in an input stream and reset back tothat point You'll also learn how and why to close input
streams This is all drawn together with a StreamCopier
program that copies data read from an input stream onto
an output stream This program is used repeatedly over thenext several chapters
Part II: Data Sources
Part II talks about the two most common targets of I/O, thefilesystem and the network While both are accessed using
Trang 16developing a File Viewer program, an example that will
grow as the book progresses This initial version prints theraw bytes in a file in both decimal and hexadecimal format
Chapter 5, Network Streams
From its first days, Java, more than any other common
programming language, has always had the network in
mind Java is the first programming language to provide asmuch support for network I/O as it does for file I/O,
perhaps even more Chapter 5 introduces the URL,
URLConnection, Socket, and ServerSocket classes, all fertile
sources of streams Examples in this chapter include severalsimple web and email clients
Part III: Filter Streams
Some of the most interesting possibilities arise when you usestreams not just for input and output but also for processing.Streaming processing simplifies code, vastly reduces memoryusage, and dramatically increases perceived performance A lotcan happen when you don't try to read everything into a
Trang 17Chapter 6, Filter Streams
Chapter 6 introduces filter streams Filter input streamsread data from a preexisting input stream such as a
delivered to the client program Filter output streams writedata to a preexisting output stream such as a
the underlying stream Multiple filters can be chained onto asingle underlying stream to combine the functionality
offered by several filters Filter streams are used for
encryption, compression, translation, buffering, and muchmore At the end of this chapter, I redesign the File Viewerprogram around filter streams to make it more extensible
Chapter 7, Print Streams
Chapter 7 introduces PrintStream The most familiar example
of a PrintStream is System.out, which is used for the very firstHello World example However, starting in Java 5, the
familiar PrintStream class has become a lot more powerfuland interesting Besides basic console output, it now
provides extensive capabilities for formatting numbers anddates in a straightforward and easy fashion
Chapter 8, Data Streams
Chapter 8 introduces data streams for writing strings,
integers, floating-point numbers, and other data that's
Trang 18primitive Java data types (boolean, int, double, etc.) and
strings in a particular, well-defined, platform-independentformat Along the way, you'll develop classes to read andwrite little-endian numbers, and you'll extend the File
Viewer program to handle big- and little-endian integersand floating-point numbers of varying widths
Chapter 9, Streams in Memory
Chapter 9 shows you how streams can move data from onepart of a running Java program to another There are threemain ways to do this Sequence input streams chain severalinput 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 turn output from one threadinto input for another thread
Chapter 10, Compressing Streams
Chapter 10 explores the java.util.zip package that readsand writes data in zip and gzip formats Java uses theseclasses to read and write JAR archives and to display PNGimages However, the java.util.zip classes can also be usedfor general-purpose compression and decompression In thefinal example, I add support for compressed files is added
to the File Viewer program
Chapter 11, JAR Archives
Many Java programs store content in JAR archives Among
Trang 19different files and resources into a single distributable
Chapter 11 explores the java.util.jar package used to readthese archives In this chapter, you'll learn when to replacefilesystems with unitary JAR archives, how to put contentinto those archives, and how to get that content back outagain
Chapter 12, Cryptographic Streams
The core Java API contains two cryptography-related filterstreams in the java.security package, DigestInputStream and
package, CipherInputStream and CipherOutputStream, available inthe Java Cryptography Extension™ (JCE for short) Chapter
12 shows you how to use these classes to encrypt and
decrypt data using a variety of algorithms, including DESand Blowfish You'll also learn how to calculate messagedigests for streams that can be used for digital signatures
In the final example, I add support for encrypted files to theFile Viewer program
Chapter 13, Object Serialization
Most I/O is performed with bytes Occasionally, larger typeslike ints, floats, and doubles are converted to bytes and
written as well However, most actual programming is donewith classes and objects Object serialization lets you readand write almost arbitrary objects onto a stream This
chapter shows you how to read and write objects as well ashow to customize the format used for serialization
Part IV: New I/O
Trang 20channels and buffers instead of streams This model doesn'treplace traditional stream-based I/O for many uses However, it
is significantly faster in one important use case: servers thatprocess many simultaneous clients
Chapter 14, Buffers
Chapter 14 introduces the buffer classes that underlie all ofthe new I/O models It demonstrates the use of the new I/Oclasses to read and write files and shows how memory-
mapped I/O enables you to read and write truly huge filesefficiently with limited memory
Chapter 15, Channels
Chapter 15 moves the new I/O model onto the network withchannels You'll learn how to combine channels through
scattering and gathering, how to communicate over socketswith channels, and how to transmit UDP packets in the newI/O model
Chapter 16, Nonblocking I/O
The real performance gain of new I/O is in highly
multiprocessing servers This chapter demonstrates the use
of nonblocking I/O to dramatically increase the number ofsimultaneous clients one program can serve You'll learnabout selectors, selection keys, attachments, and pipe
channels
Part V: The File System
Trang 21Part V discusses operations on files themselves as distinct fromthe contents of those files This includes moving, deleting,
renaming, and choosing them
Chapter 17, Working with Files
Files can be moved, deleted, renamed, and copied Filesusually have metadata such as the time the file was
created, the icon for the file, and the permissions that
determine which users can read or write the file Chapter 17
shows you how to do all this and elaborates the precautionsyou need to take to make your file code portable across allmajor platforms that support Java
Chapter 18, File Dialogs and Choosers
Filenames are problematic, even if you don't have to worryabout cross-platform idiosyncrasies Users forget names,mistype them, can't remember the exact path to files theyneed, and more The proper way to ask a user to choose afile is to show him a list of the files and ask him to pick one.Most graphical user interfaces provide standard graphicalwidgets for selecting a file In Java, the platform's nativefile selector widget is exposed through the java.awt.FileDialog
class Like many native peer-based classes, however,
services on all platforms Therefore, Swing provides a pureJava implementation of a file dialog, the
based GUI to the File Viewer program
Trang 22to use these classes to add support for multilingual text tothe File Viewer program.
Trang 23Computers process numbers, not words When outputtingbinary numbers as decimal strings for humans to read, the
Part VII: Devices
Not everything is a filesystem or a network I/O also includestalking to other kinds of devices: laboratory sensors, PDAs, andhuman input devices such as mice and keyboards While
common devices such as mice and keyboards are addressedthrough higher-level APIs, less common devices such as
laboratory equipment are not This section shows you how tocommunicate with different kinds of peripherals and small
scanner, or modem
Trang 24Serial and parallel ports are still found on a lot of legacyequipment, but most new devices have moved on USB isthe next generation serial connector, and Java supports it
Chapter 23 shows you how to talk to a variety of USB
devices using the Java USB API In particular, it
demonstrates collecting data from a USB-enabled laboratorytemperature probe
Chapter 24, The J2ME Generic Connection Framework
Some small devices are computers in their own rights: PalmPilots, cell phones, programmable calculators, and others.However, these devices don't always have the CPU speed,memory, or battery life necessary to run a full-scale Java
VM Many of them run one of a variety of slimmed-downvirtual machines that collectively go by the name J2ME Thestandard java.io and java.net packages are too heavyweight
to fit in many such small devices This chapter introducesthe smaller, simpler Generic Connection Framework (GCF)
I/O library on small devices
Chapter 25, Bluetooth
Increasingly, small devices don't even need cables in order
to connect to a host system Instead, they transmit dataover the air using Bluetooth Chapter 25 explores the JavaAPI for Bluetooth and shows you how Java programs cantalk to Bluetooth devices wirelessly using the GCF One
example shows how to read location data from a Bluetooth
Trang 25Chapters 1 through 6 provide the basic background you'llneed to do any sort of work with I/O in Java After that, youshould feel free to jump around wherever your intereststake you There are, however, some interdependencies
between specific chapters Figure P-1 should help you mapout possible paths through the book
Figure P-1 Chapter prerequisites
Trang 26not be difficult to understand on the whole
Who You Are
This book assumes you have a basic familiarity with Java Youshould be thoroughly familiar with the syntax of the language.You should be comfortable with object-oriented programming,including terminology like instances, objects, and classes Youshould know what a reference is and what that means for
passing arguments to and returning values from methods Youshould already have written simple applications and applets
For the most part, I try to keep the examples relatively
straightforward so that they require only minimal understanding
of other parts of the class library outside the I/O classes Thismay lead some to deride these as "toy examples." However, Ifind that such examples are far more conducive to
understanding and learning than are full-blown, sophisticatedprograms that fill page after page with graphical user interface(GUI) 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 JStreamedTextArea class in Chapter 2
or the File Viewer application developed throughout most of thebook I will try to keep the GUI material to a minimum, but afamiliarity with the basics of the AWT and Swing will be
assumed
When you encounter a topic that requires a deeper
understanding of I/O than is customaryfor instance, the exactnature of stringsI'll cover that topic as well, at least briefly
However, this is not a language tutorial, and the emphasis willalways be on the I/O-specific features
Trang 27java package hierarchy For instance, Chapter 2's NullOutputStream
class is in the com.elharo.io package When working with these
Constant width
Used in all Java code and generally for anything that youwould type literally when programming, including keywords,data types, constants, method names, variables, class
names, and interface names
Trang 28Used as a placeholder to indicate an item that should bereplaced with an actual value in your program
Constant width bold
Used for user input on the command line
Request for Comments
I enjoy hearing from readers, whether with general commentsabout how this could be a better book, specific corrections, orother topics you would like to see covered You can reach me bysending email to elharo@metalab.unc.edu Please realize,
however, that I receive several hundred pieces of email a dayand cannot personally respond to each one
I'm especially interested in hearing about mistakes If you findone, I'll post it on my web page for this book at
http://www.cafeaulait.org/books/javaio2/ and on the O'Reillyweb site at http://www.oreilly.com/catalog/javaio2/ Before
reporting errors, please check one of those pages to see if Ialready know about it and have posted a fix
Safari Enabled
When you see the Safari® Enabled icon on the backcover of your favorite technology book, that means the book isavailable online through the O'Reilly Network Safari Bookshelf.Safari offers a solution that's better than e-books It's a virtuallibrary that lets you easily search thousands of top technology
Trang 29Try it for free at http://safari.oreilly.com
Acknowledgments
Many people were involved in the production of this book Allthese people deserve much thanks and credit My editor, MikeLoukides, got this book rolling and provided many helpful
comments that substantially improved it Deb Cameron stepped
up to the plate to edit this second edition Clairemarie FisherO'Leary, Chris Maden, and Robert Romano deserve a specialcommendation for putting in all the extra effort needed for abook that makes free use of Arabic, Cyrillic, Chinese, and othernon-Roman scripts Tim O'Reilly and the whole crew at O'Reillydeserve special thanks for building a publisher that's willing togive a book the time and support it needs to be a good bookrather 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, BobEckstein, and Avner Gelb Bruce Schneier and Jan Luehe bothlent their expertise to the cryptography chapter Ron Hitchensshone light into many of the darker areas of the new I/O APIs.Ian Darwin was invaluable in handling the details of the JavaCommunications API Jonathan Knudsen helped out with
Bluetooth and The GCF IBM's Dan Streetman assisted with
understanding the Java USB API (as well as writing the opensource reference implementation I used), and Avetana's MoritzGmelin was equally helpful with some tricky points of workingwith the Java Bluetooth API
Finally, I'd like to save my largest thanks for my wife, Beth,
without whose support and assistance this book would neverhave happened
Trang 30May 2, 2006
Trang 31
Chapter 1: Introducing I/OChapter 2: Output StreamsChapter 3: Input Streams
Trang 32
Input and output, I/O for short, are fundamental to any
computer operating system or programming language Onlytheorists find it interesting to write programs that don't requireinput or produce output At the same time, I/O hardly qualifies
as one of the more "thrilling" topics in computer science It'ssomething in the background, something you use every daybutfor most developers, it's not a topic with much sex appeal
But in fact, there are plenty of reasons Java programmers
should find I/O interesting Java includes a particularly rich set
of I/O classes in the core API, mostly in the java.io and java.nio
packages These packages support several different styles ofI/O One distinction is between byte-oriented I/O, which is
handled by input and output streams, and character-I/O, which
is handled by readers and writers Another distinction is
between the old-style stream-based I/O and the new-style
channel- and buffer-based I/O These all have their place andare appropriate for different needs and use cases None of themshould be ignored
Java's I/O libraries are designed in an abstract way that enablesyou to read from external data sources and write to externaltargets, regardless of the kind of thing you're writing to or
reading from You use the same methods to read from a filethat you do to read from the console or from a network
connection You use the same methods to write to a file thatyou do to write to a byte array or a serial port device
Reading and writing without caring where your data is comingfrom or where it's going is a very powerful abstraction Amongother things, this enables you to define I/O streams that
automatically compress, encrypt, and filter from one data
format to another Once you have these tools, programs cansend encrypted data or write zip files with almost no knowledge
Trang 33In this book, I'll take a thorough look at all parts of Java's I/Ofacilities This includes all the different kinds of streams you canuse and the channels and buffers that offer high-performance,high-throughput, nonblocking operations on servers We're alsogoing to investigate Java's support for Unicode We'll look atJava's powerful facilities for formatting I/O Finally, we'll look atthe various APIs Java provides for low-level I/O through variousdevices including serial ports, parallel ports, USB, Bluetooth,and other hardware you'll find in devices that don't necessarilylook like a traditional desktop computer or server
I won't go so far as to say, "If you've always found I/O boring,this is the book for you!" I will say that if you do find I/O
uninteresting, you probably don't know as much about it as youshould I/O is the means for communication between softwareand the outside world Java provides a powerful and flexible set
of tools for doing this crucial part of the job Having said that,let's start with the basics
Trang 34A stream is an ordered sequence of bytes of indeterminate
length Input streams move bytes of data into a Java programfrom some generally external source Output streams movebytes of data from Java to some generally external target (Inspecial cases, streams can also move bytes from one part of aJava program to another.)
The word stream is derived from an analogy between a
sequence and a stream of water An input stream is like a
siphon that sucks up water; an output stream is like a hose thatsprays out water Siphons can be connected to hoses to movewater from one place to another Sometimes a siphon may runout of water if it's drawing from a finite source like a bucket Onthe other hand, if the siphon is drawing water from a river, itmay well operate indefinitely So, too, an input stream may
read from a finite source of bytes such as a file or an unlimitedsource of bytes such as System.in Similarly, an output streammay have a definite number of bytes to output or an indefinitenumber of bytes
Input to a Java program can come from many sources Outputcan go to many different kinds of destinations The power of thestream metaphor is that the differences between these sourcesand destinations are abstracted away All input and output
operations are simply treated as streams using the same
classes and the same methods You don't need to learn a newAPI for every different kind of device The same API that readsfiles can read network sockets, serial ports, Bluetooth
transmissions, and more
1.1.1 Where Do Streams Come From?
Trang 35of console window, probably the one in which the Java programwas launched If input is redirected so the program reads from
a file, then System.in is changed as well For instance, on Unix,the following command redirects stdin so that when the
comes from the file data.txt instead of from the console:
% java MessageServer < data.txt
The console is also available for output through the static field
out in the java.lang.System class, that is, System.out This is
equivalent to stdout in C parlance and may be redirected in asimilar fashion Finally, stderr is available as System.err This ismost commonly used for debugging and printing error
messages from inside catch clauses For example:
try {
// do something that might throw an exception}
catch (Exception ex) {
System.err.println(ex);
}
Both System.out and System.err are print streamsthat is, instances
7
Files are another common source of input and destination foroutput File input streams provide a stream of data that startswith the first byte in a file and finishes with the last byte in thatfile File output streams write data into a file, either by erasing
Trang 36group of bytes provided as data for a stream must have a fixedorder However, users can change the contents of a text area or
a text field at any point, not just at the end Furthermore, theycan delete text from the middle of a stream while a differentthread is reading that data Hence, streams aren't a good
metaphor for reading data from GUI components You can,
however, use the strings they do produce to create a byte arrayinput stream or a string reader
1.1.2 The Stream Classes
Most of the classes that work directly with streams are part of
many different subclasses with more specialized abilities
The subclasses include:
BufferedInputStream
BufferedOutputStream
Trang 39Input streams read bytes and output streams write bytes
Readers read characters and writers write characters
Therefore, to understand input and output, you first need asolid understanding of how Java deals with bytes, integers,
characters, and other primitive data types, and when and whyone is converted into another In many cases Java's behavior isnot obvious
1.2.1 Integer Data
The fundamental integer data type in Java is the int, a 4-byte,big-endian, two's complement integer An int can take on allvalues between -2,147,483,648 and 2,147,483,647 When youtype a literal integer such as 7, -8345, or 3000000000 in Javasource code, the compiler treats that literal as an int In thecase of 3000000000 or similar numbers too large to fit in an
Two more integer data types are available in Java, the short and
integers with ranges from -32,768 to 32,767 They're rarelyused in Java and are included mainly for compatibility with C
Trang 40they're used in I/O A byte is an 8-bit, two's complement integerthat ranges from -128 to 127 Note that like all numeric datatypes in Java, a byte is signed The maximum byte value is 127
128, 129, and so on through 255 are not legal values for bytes
Java has no short or byte literals When you write the literal 42 or
24000, the compiler always reads it as an int, never as a byte or