⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij0185.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<font color="#009900">// prove defective, you assume the cost of all</font>
<font color="#009900">// necessary servicing, repair, or correction. If you</font>
<font color="#009900">// think you've found an error, please email all</font>
<font color="#009900">// modified files with clearly commented changes to:</font>
<font color="#009900">// Bruce@EckelObjects.com. (please use the same</font>
<font color="#009900">// address for non-code errors found in the book).</PRE></font></font><DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=2 COLOR="Black">//////////////////////////////////////////////////</FONT></TT><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
extracting files from a packed file, the file separator of the system that
packed the file is also noted, so it can be replaced with the correct one for
the local system.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
subdirectory name for the current chapter is kept in the field 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>chapter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which is initialized to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c02</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
(You&#8217;ll notice that the listing in Chapter 2 doesn&#8217;t contain a
package statement.) The only time that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>chapter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
field changes is when a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>package</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
statement is discovered in the current file.
</FONT><P></DIV>
<A NAME="Heading574"></A><H4 ALIGN=LEFT>
Building
a packed file
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first constructor is used to extract a file from the ASCII text version of this
book. The calling code (which appears further down in the listing) reads each
line in until it finds one that matches the beginning of a listing. At that
point, it creates a new 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SourceCodeFile</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object, passing it the first line (which has already been read by the calling
code) and the <A NAME="Index3022"></A><A NAME="Index3023"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BufferedReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object from which to extract the rest of the source code listing.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">At
this point, you begin to see heavy use of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods. To extract the file name, the overloaded version of <A NAME="Index3024"></A><A NAME="Index3025"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>substring(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is called that takes the starting offset and goes to the end of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This starting index is produced by finding the <A NAME="Index3026"></A><A NAME="Index3027"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>length(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>startMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
<A NAME="Index3028"></A><A NAME="Index3029"></A>trim(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
removes white space from both ends of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The first line can also have words after the name of the file; these are
detected using <A NAME="Index3030"></A><A NAME="Index3031"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>indexOf(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which returns -1 if it cannot find the character you&#8217;re looking for and
the value where the first instance of that character is found if it does.
Notice there is also an overloaded version of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>indexOf(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that takes a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
instead of a character.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Once
the file name is parsed and stored, the first line is placed into the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(which is used to hold the entire text of the source code listing). At this
point, the rest of the lines are read and concatenated into the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It&#8217;s not quite that simple, since certain situations require special
handling. One case is error checking: if you run into a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>startMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
it means that no end marker was placed at the end of the listing that&#8217;s
currently being collected. This is an error condition that aborts the program.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
second special case is the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>package</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword. Although Java is a free-form language, this program requires that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>package</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword be at the beginning of the line. When the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>package</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword is seen, the package name is extracted by looking for the space at the
beginning and the semicolon at the end. (Note that this could also have been
performed in a single operation by using the overloaded 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>substring(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that takes both the starting and ending indexes.) Then the dots in the package
name are replaced by the file separator, although an assumption is made here
that the file separator is only one character long. This is probably true on
all systems, but it&#8217;s a place to look if there are problems.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
default behavior is to concatenate each line to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
along with the end-of-line string, until the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>endMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is discovered, which indicates that the constructor should terminate. If the
end of the file is encountered before the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>endMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is seen, that&#8217;s an error.
</FONT><P></DIV>
<A NAME="Heading575"></A><H4 ALIGN=LEFT>
Extracting
from a packed file
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
second constructor is used to recover the source code files from a packed file.
Here, the calling method doesn&#8217;t have to worry about skipping over the
intermediate text. The file contains all the source-code files, placed
end-to-end. All you need to hand to this constructor is the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BufferedReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
where the information is coming from, and the constructor takes it from there.
There is some meta-information, however, at the beginning of each listing, and
this is denoted by the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>packMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
If the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>packMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
isn&#8217;t there, it means the caller is mistakenly trying to use this
constructor where it isn&#8217;t appropriate.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Once
the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>packMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is found, it is stripped off and the directory name (terminated by a &#8216;
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>#</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;)
and the file name (which goes to the end of the line) are extracted. In both
cases, the old separator character is replaced by the one that is current to
this machine using the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String
<A NAME="Index3032"></A><A NAME="Index3033"></A>replace(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method. The old separator is placed at the beginning of the packed file, and
you&#8217;ll see how that is extracted later in the listing.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
rest of the constructor is quite simple. It reads and concatenates each line to
the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
until the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>endMarker</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is found.
</FONT><P></DIV>
<A NAME="Heading576"></A><H4 ALIGN=LEFT>
Accessing
and writing the listings
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
next set of methods are simple accessors: 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>directory(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>filename(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(notice the method can have the same spelling and capitalization as the field)
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>contents(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>hasFile(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to indicate whether this object contains a file or not. (The need for this will
be seen later.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
final three methods are concerned with writing this code listing into a file,
either a packed file via 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writePacked(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or a Java source file via 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeFile(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
All 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writePacked(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
needs is the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataOutputStream,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
which was opened elsewhere, and represents the file that&#8217;s being written.
It puts the header information on the first line and then calls 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeBytes(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to write 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in a &#8220;universal&#8221; format.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
writing the Java source file, the file must be created. This is done via 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>IO.psOpen(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
handing it a <A NAME="Index3034"></A><A NAME="Index3035"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>File</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object that contains not only the file name but also the path. But the question
now is: does this path exist? The user has the option of placing all the source
code directories into a completely different subdirectory, which might not even
exist. So before each file is written, <A NAME="Index3036"></A><A NAME="Index3037"></A><A NAME="Index3038"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>File.mkdirs(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is called with the path that you want to write the file into. This will make
the entire path all at once.
</FONT><P></DIV>
<A NAME="Heading577"></A><H4 ALIGN=LEFT>
Containing
the entire collection of listings
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It&#8217;s
convenient to organize the listings as subdirectories while the whole
collection is being built in memory. One reason is another sanity check: as
each subdirectory of listings is created, an additional file is added whose
name contains the number of files in that directory.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DirMap</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class produces this effect and demonstrates the concept of a
&#8220;multimap.&#8221; This is implemented using a <A NAME="Index3039"></A><A NAME="Index3040"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
whose keys are the subdirectories being created and whose values are <A NAME="Index3041"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects containing the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SourceCodeFile</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects in that particular directory. Thus, instead of mapping a key to a
single value, the &#8220;multimap&#8221; maps a key to a set of values via the
associated 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Although this sounds complex, it&#8217;s remarkably straightforward to
implement. You&#8217;ll see that most of the size of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DirMap</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class is due to the portions that write to files, not to the
&#8220;multimap&#8221; implementation.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There
are two ways you can make a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DirMap</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
the default constructor assumes that you want the directories to branch off of
the current one, and the second constructor lets you specify an alternate
absolute path for the starting directory.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -