📄 chap11.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<!--
This document was converted from RTF source:
By rtftohtml 4.19
See http://www.sunpack.com/RTF
Filename:TIJ2.rtf
Application Directory:C:\TOOLS\RTF2HTML\
Subject:
Author:Bruce Eckel
Operator:Bruce Eckel
Document Comments:
Version Comments:
Comments:
Keywords:
Translation Date:05/21/2001
Translation Time:10:39:18
Translation Platform:Win32
Number of Output files:23
This File:Chap11.htm
SplitDepth=1
SkipNavPanel=1
SkipLeadingToc=1
SkipTrailingToc=1
GenContents=1
GenFrames=1
GenIndex=1
-->
<HEAD lang="en"><META http-equiv="Content-Type" content="text/html">
<TITLE>11: The Java I/O System</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF"><DIV ALIGN="CENTER">
<a href="http://www.MindView.net">
<img src="mindview.gif" alt="MindView Inc." BORDER = "0"></a>
<CENTER>
<FONT FACE="Verdana" size = "-1">
[ <a href="README.txt">Viewing Hints</a> ]
[ <a href="RevHist.htm">Revision History</a> ]
[ <a href="http://www.mindview.net/Books/TIJ/">Book Home Page</a> ]
[ <a href="http://www.mindview.net/Etc/MailingList.html">Free Newsletter</a> ] <br>
[ <a href="http://www.mindview.net/Seminars">Seminars</a> ]
[ <a href="http://www.mindview.net/CDs">Seminars on CD ROM</a> ]
[ <a href="http://www.mindview.net/Services">Consulting</a> ]
</FONT>
<H2><FONT FACE="Verdana">
Thinking in Java, 2nd edition, Revision 12</FONT></H2>
<H3><FONT FACE="Verdana">©2000 by Bruce Eckel</FONT></H3>
<FONT FACE="Verdana" size = "-1">
[ <a href="Chap10.htm">Previous Chapter</a> ]
[ <a href="SimpCont.htm">Short TOC</a> ]
[ <a href="Contents.htm">Table of Contents</a> ]
[ <a href="DocIdx.htm">Index</a> ]
[ <a href="Chap12.htm">Next Chapter</a> ]
</FONT>
</CENTER>
</P></DIV><A NAME="Chapter_10"></A><A NAME="_Toc375545381"></A><A NAME="_Toc477690731"></A><A NAME="_Toc481064734"></A><A NAME="Heading353"></A><FONT FACE = "Verdana"><H1 ALIGN="LEFT">
11: The Java <BR>I/O System</H1></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia" SIZE=4><backtalk:display ID=TIJ3_CHAPTER11_I0>
Creating
a good input/output (I/O) system is one of the more difficult tasks for the
language designer.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This is evidenced by the number of
different approaches. The challenge seems to be in covering all eventualities.
Not only are there different sources and sinks of I/O that you want to
communicate with (files, the console, network connections), but you need to talk
to them in a wide variety of ways (sequential, random-access, buffered, binary,
character, by lines, by words, etc.).
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I0'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I1>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The Java library designers attacked this
problem by creating lots of classes. In fact, there are so many classes for
Java’s I/O system that it can be intimidating at first (ironically, the
Java I/O design actually prevents an explosion of classes). There was also a
significant change in the I/O <A NAME="Index1128"></A>library after Java 1.0,
when the original <B>byte</B>-oriented library was supplemented with
<B>char</B>-oriented, Unicode-based I/O classes. As a result there are a fair
number of classes to learn before you understand enough of Java’s I/O
picture that you can use it properly. In addition, it’s rather important
to understand the evolution history of the I/O library, even if your first
reaction is “don’t bother me with history, just show me how to use
it!” The problem is that without the historical perspective you will
rapidly become confused with some of the classes and when you should and
shouldn’t use them.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I1'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I2>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This chapter will give you an
introduction to the variety of I/O classes in the standard Java library and how
to use them.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I2'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I3>
</FONT><A NAME="_Toc375545382"></A><A NAME="_Toc375545390"></A><A NAME="_Toc481064735"></A><BR></P></DIV>
<A NAME="Heading354"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
The File
class<BR><A NAME="Index1129"></A><A NAME="Index1130"></A><A NAME="Index1131"></A><A NAME="Index1132"></A><A NAME="Index1133"></A><A NAME="Index1134"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Before getting into the classes that
actually read and write data to streams, we’ll look a utility provided
with the library to assist you in handling file directory issues.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I3'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I4>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>File </B>class has a deceiving
name—you might think it refers to a file, but it doesn’t. It can
represent either the <I>name</I> of a particular file or the <I>names</I> of a
set of files in a directory. If it’s a set of files, you can ask for the
set with the <B>list( )</B> method, and this returns an array of
<B>String</B>. It makes sense to return an array rather than one of the flexible
container classes because the number of elements is fixed, and if you want a
different directory listing you just create a different <B>File</B> object. In
fact, “FilePath” would have been a better name for the class. This
section shows an example of the use of this class, including the associated
<B>FilenameFilter</B> <B>interface</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I4'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I5>
</FONT><A NAME="_Toc375545391"></A><A NAME="_Toc481064736"></A><BR></P></DIV>
<A NAME="Heading355"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
A directory lister<BR><A NAME="Index1135"></A><A NAME="Index1136"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Suppose you’d like to see a
directory listing. The <B>File</B> object can be listed in two ways. If you call
<B>list( )</B> with no arguments, you’ll get the full list that the
<B>File</B> object contains. However, if you want a restricted list—for
example, if you want all of the files with an extension of
<B>.java</B>—then you use a “directory filter,” which is a
class that tells how to select the <B>File</B> objects for display.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I5'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I6>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here’s the code for the example.
Note that the result has been effortlessly sorted (alphabetically) using the
<B>java.utils.Array.sort( )</B> method and the <B>AlphabeticComparator</B>
defined in Chapter 9:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c11:DirList.java</font>
<font color=#009900>// Displays directory listing.</font>
<font color=#0000ff>import</font> java.io.*;
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>import</font> com.bruceeckel.util.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> DirList {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
File path = <font color=#0000ff>new</font> File(<font color=#004488>"."</font>);
String[] list;
<font color=#0000ff>if</font>(args.length == 0)
list = path.list();
<font color=#0000ff>else</font>
list = path.list(<font color=#0000ff>new</font> DirFilter(args[0]));
Arrays.sort(list,
<font color=#0000ff>new</font> AlphabeticComparator());
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < list.length; i++)
System.out.println(list[i]);
}
}
<font color=#0000ff>class</font> DirFilter <font color=#0000ff>implements</font> FilenameFilter {
String afn;
DirFilter(String afn) { <font color=#0000ff>this</font>.afn = afn; }
<font color=#0000ff>public</font> <font color=#0000ff>boolean</font> accept(File dir, String name) {
<font color=#009900>// Strip path information:</font>
String f = <font color=#0000ff>new</font> File(name).getName();
<font color=#0000ff>return</font> f.indexOf(afn) != -1;
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>DirFilter</B> class
“implements” the <B>interface</B> <B>FilenameFilter</B>. It’s
useful to see how simple the <B>FilenameFilter</B> <B>interface</B> is:
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I6'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I7>
</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>public</font> <font color=#0000ff>interface</font> FilenameFilter {
<font color=#0000ff>boolean</font> accept(File dir, String name);
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It says all that this type of object does
is provide a method called <B>accept( )</B>. The whole reason behind the
creation of this class is to provide the <B>accept( )</B> method to the
<B>list( )</B> method so that <B>list( )</B> can “call
back” <B>accept( )</B> to determine which file names should be
included in the list. Thus, this technique is often referred to as a
<A NAME="Index1137"></A><I>callback</I> or sometimes a
<A NAME="Index1138"></A><I>functor</I> (that is, <B>DirFilter</B> is a functor
because its only job is to hold a method) or the
<A NAME="Index1139"></A><A NAME="Index1140"></A><I>Command</I> <I>Pattern</I>.
Because <B>list( )</B> takes a <B>FilenameFilter</B> object as its
argument, it means that you can pass an object of any class that implements
<B>FilenameFilter</B> to choose (even at run-time) how the <B>list( )</B>
method will behave. The purpose of a callback is to provide flexibility in the
behavior of code.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I7'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I8>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>DirFilter</B> shows that just because
an <B>interface</B> contains only a set of methods, you’re not restricted
to writing only those methods. (You must at least provide definitions for all
the methods in an interface, however.) In this case, the <B>DirFilter</B>
constructor is also created.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I8'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I9>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>accept( )</B> method must
accept a <B>File</B> object representing the directory that a particular file is
found in, and a <B>String</B> containing the name of that file. You might choose
to use or ignore either of these arguments, but you will probably at least use
the file name. Remember that the <B>list( )</B> method is calling
<B>accept( )</B> for each of the file names in the directory object to see
which one should be included—this is indicated by the <B>boolean</B>
result returned by <B>accept( )</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I9'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I10>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To make sure the element you’re
working with is only the file name and contains no path information, all you
have to do is take the <B>String</B> object and create a <B>File</B> object out
of it, then call <B>getName( )</B>, which strips away all the path
information (in a platform-independent way). Then <B>accept( )</B> uses the
<A NAME="Index1141"></A><A NAME="Index1142"></A><B>String </B>class
<B>indexOf( )</B> method to see if the search string <B>afn</B> appears
anywhere in the name of the file. If <B>afn</B> is found within the string, the
return value is the starting index of <B>afn</B>, but if it’s not found
the return value is -1. Keep in mind that this is a simple string search and
does not have “glob” expression wildcard matching—such as
“fo?.b?r*”—which is much more difficult to implement.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I10'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I11>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>list( )</B> method returns an
array. You can query this array for its length and then move through it
selecting the array elements. This ability to easily pass an array in and out of
a method is a tremendous improvement over the behavior of C and C++.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER11_I11'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER11_I12>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -