📄 tij0185.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0184.html">Prev</a> | <a href="tij0186.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
Text
processing
<P><A NAME="Index3011"></A></H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you come from a C or C++ background, you might be skeptical at first of
Java’s power when it comes to handling text. Indeed, one drawback is that
execution speed is slower and that could hinder some of your efforts. However,
the tools (in particular the <A NAME="Index3012"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class) are quite powerful, as the examples in this section show (and
performance improvements have been promised for Java).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">As
you’ll see, these examples were created to solve problems that arose in
the creation of this book. However, they are not restricted to that and the
solutions they offer can easily be adapted to other situations. In addition,
they show the power of Java in an area that has not previously been emphasized
in this book.
</FONT><a name="_Toc375545503"></a><a name="_Toc408018811"></a><P></DIV>
<A NAME="Heading573"></A><H3 ALIGN=LEFT>
Extracting
code listings
<P><A NAME="Index3013"></A><A NAME="Index3014"></A><A NAME="Index3015"></A><A NAME="Index3016"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You’ve
no doubt noticed that each complete code listing (not code fragment) in this
book begins and ends with special comment tag marks ‘
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>//:</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">’
and ‘
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>///:~</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">’.
This meta-information is included so that the code can be automatically
extracted from the book into compilable source-code files. In my previous book,
I had a system that allowed me to automatically incorporate tested code files
into the book. In this book, however, I discovered that it was often easier to
paste the code into the book once it was initially tested and, since it’s
hard to get right the first time, to perform edits to the code within the book.
But how to extract it and test the code? This program is the answer, and it
could come in handy when you set out to solve a text processing problem. It
also demonstrates many 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">
class features.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">I
first save the entire book in ASCII text format into a separate file. The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CodePackager</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
program has two modes (which you can see described in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>usageString</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">):
if you use the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-p</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
flag, it expects to see an input file containing the ASCII text from the book.
It will go through this file and use the comment tag marks to extract the code,
and it uses the file name on the first line to determine the name of the file.
In addition, it looks for the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>package</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
statement in case it needs to put the file into a special directory (chosen via
the path indicated by the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>package</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
statement).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">But
that’s not all. It also watches for the change in chapters by keeping
track of the package names. Since all packages for each chapter begin with
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c02</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c03</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c04</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
etc. to indicate the chapter where they belong
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">(except
for those beginning with
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>com</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which are ignored for the purpose of keeping track of chapters), as long as the
first listing in each chapter contains 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 with the chapter number, the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CodePackager</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
program can keep track of when the chapter changed and put all the subsequent
files in the new chapter subdirectory.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">As
each file is extracted, it is placed into a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SourceCodeFile</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object that is then placed into a collection. (This process will be more
thoroughly described later.) These
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SourceCodeFile</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects could simply be stored in files, but that brings us to the second use
for this project. If you invoke
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CodePackager</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>without</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-p</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
flag it expects a “packed” file as input, which it will then
extract into separate files. So the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-p</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
flag means that the extracted files will be found “packed” into
this single file.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Why
bother with the packed file? Because different computer platforms have
different ways of storing text information in files. A big issue is the
end-of-line character or characters, but other issues can also exist. However,
Java has a special type of IO stream – the <A NAME="Index3017"></A><A NAME="Index3018"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataOutputStream
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">–
which promises that, regardless of what machine the data is coming from, the
storage of that data will be in a form that can be correctly retrieved by any
other machine by using a <A NAME="Index3019"></A><A NAME="Index3020"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
That is, Java handles all of the <A NAME="Index3021"></A>platform-specific
details, which is a large part of the promise of Java. So the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-p</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
flag stores everything into a single file in a universal format. You download
this file and the Java program from the Web, and when you run
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CodePackager</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
on this file
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>without</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-p</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
flag the files will all be extracted to appropriate places on your system. (You
can specify an alternate subdirectory; otherwise the subdirectories will just
be created in the current directory.) To ensure that no system-specific formats
remain,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>File</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects are used everywhere a path or a file is described. In addition,
there’s a sanity check: an empty file is placed in each subdirectory; the
name of that file indicates how many files you should find in that subdirectory.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here
is the code, which will be described in detail at the end of the listing:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: CodePackager.java</font>
<font color="#009900">// "Packs" and "unpacks" the code in "Thinking </font>
<font color="#009900">// in Java" for cross-platform distribution.</font>
<font color="#009900">/* Commented so CodePackager sees it and starts
a new chapter directory, but so you don't
have to worry about the directory where this
program lives:
package c17;
*/</font>
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">class</font> Pr {
<font color="#0000ff">static</font> <font color="#0000ff">void</font> error(String e) {
System.err.println("ERROR: " + e);
System.exit(1);
}
}
<font color="#0000ff">class</font> IO {
<font color="#0000ff">static</font> BufferedReader disOpen(File f) {
BufferedReader in = <font color="#0000ff">null</font>;
<font color="#0000ff">try</font> {
in = <font color="#0000ff">new</font> BufferedReader(
<font color="#0000ff">new</font> FileReader(f));
} <font color="#0000ff">catch</font>(IOException e) {
Pr.error("could not open " + f);
}
<font color="#0000ff">return</font> in;
}
<font color="#0000ff">static</font> BufferedReader disOpen(String fname) {
<font color="#0000ff">return</font> disOpen(<font color="#0000ff">new</font> File(fname));
}
<font color="#0000ff">static</font> DataOutputStream dosOpen(File f) {
DataOutputStream in = <font color="#0000ff">null</font>;
<font color="#0000ff">try</font> {
in = <font color="#0000ff">new</font> DataOutputStream(
<font color="#0000ff">new</font> BufferedOutputStream(
<font color="#0000ff">new</font> FileOutputStream(f)));
} <font color="#0000ff">catch</font>(IOException e) {
Pr.error("could not open " + f);
}
<font color="#0000ff">return</font> in;
}
<font color="#0000ff">static</font> DataOutputStream dosOpen(String fname) {
<font color="#0000ff">return</font> dosOpen(<font color="#0000ff">new</font> File(fname));
}
<font color="#0000ff">static</font> PrintWriter psOpen(File f) {
PrintWriter in = <font color="#0000ff">null</font>;
<font color="#0000ff">try</font> {
in = <font color="#0000ff">new</font> PrintWriter(
<font color="#0000ff">new</font> BufferedWriter(
<font color="#0000ff">new</font> FileWriter(f)));
} <font color="#0000ff">catch</font>(IOException e) {
Pr.error("could not open " + f);
}
<font color="#0000ff">return</font> in;
}
<font color="#0000ff">static</font> PrintWriter psOpen(String fname) {
<font color="#0000ff">return</font> psOpen(<font color="#0000ff">new</font> File(fname));
}
<font color="#0000ff">static</font> <font color="#0000ff">void</font> close(Writer os) {
<font color="#0000ff">try</font> {
os.close();
} <font color="#0000ff">catch</font>(IOException e) {
Pr.error("closing " + os);
}
}
<font color="#0000ff">static</font> <font color="#0000ff">void</font> close(DataOutputStream os) {
<font color="#0000ff">try</font> {
os.close();
} <font color="#0000ff">catch</font>(IOException e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -