📄 tij0113.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="tij0112.html">Prev</a> | <a href="tij0114.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
StreamTokenizer</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Although
<A NAME="Index1170"></A><A NAME="Index1171"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StreamTokenizer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is not derived from
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>OutputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
it works only with
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects, so it rightfully belongs in the IO portion of the library.
</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>StreamTokenizer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class is used to break any
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
into a sequence of<A NAME="Index1172"></A>
“tokens,” which are bits of text delimited by whatever you choose.
For example, your tokens could be words, and then they would be delimited by
white space and punctuation.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Consider
a program to count the occurrence of words in a text file:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: SortedWordCount.java</font>
<font color="#009900">// Counts words in a file, outputs</font>
<font color="#009900">// results in sorted form.</font>
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">import</font> c08.*; <font color="#009900">// Contains StrSortVector</font>
<font color="#0000ff">class</font> Counter {
<font color="#0000ff">private</font> <font color="#0000ff">int</font> i = 1;
<font color="#0000ff">int</font> read() { <font color="#0000ff">return</font> i; }
<font color="#0000ff">void</font> increment() { i++; }
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> SortedWordCount {
<font color="#0000ff">private</font> FileInputStream file;
<font color="#0000ff">private</font> StreamTokenizer st;
<font color="#0000ff">private</font> Hashtable counts = <font color="#0000ff">new</font> Hashtable();
SortedWordCount(String filename)
<font color="#0000ff">throws</font> FileNotFoundException {
<font color="#0000ff">try</font> {
file = <font color="#0000ff">new</font> FileInputStream(filename);
st = <font color="#0000ff">new</font> StreamTokenizer(file);
st.ordinaryChar('.');
st.ordinaryChar('-');
} <font color="#0000ff">catch</font>(FileNotFoundException e) {
System.out.println(
"Could not open " + filename);
<font color="#0000ff">throw</font> e;
}
}
<font color="#0000ff">void</font> cleanup() {
<font color="#0000ff">try</font> {
file.close();
} <font color="#0000ff">catch</font>(IOException e) {
System.out.println(
"file.close() unsuccessful");
}
}
<font color="#0000ff">void</font> countWords() {
<font color="#0000ff">try</font> {
<font color="#0000ff">while</font>(st.nextToken() !=
StreamTokenizer.TT_EOF) {
String s;
<font color="#0000ff">switch</font>(st.ttype) {
<font color="#0000ff">case</font> StreamTokenizer.TT_EOL:
s = <font color="#0000ff">new</font> String("EOL");
<font color="#0000ff">break</font>;
<font color="#0000ff">case</font> StreamTokenizer.TT_NUMBER:
s = Double.toString(st.nval);
<font color="#0000ff">break</font>;
<font color="#0000ff">case</font> StreamTokenizer.TT_WORD:
s = st.sval; <font color="#009900">// Already a String</font>
<font color="#0000ff">break</font>;
<font color="#0000ff">default</font>: <font color="#009900">// single character in ttype</font>
s = String.valueOf((<font color="#0000ff">char</font>)st.ttype);
}
<font color="#0000ff">if</font>(counts.containsKey(s))
((Counter)counts.get(s)).increment();
<font color="#0000ff">else</font>
counts.put(s, <font color="#0000ff">new</font> Counter());
}
} <font color="#0000ff">catch</font>(IOException e) {
System.out.println(
"st.nextToken() unsuccessful");
}
}
Enumeration values() {
<font color="#0000ff">return</font> counts.elements();
}
Enumeration keys() { <font color="#0000ff">return</font> counts.keys(); }
Counter getCounter(String s) {
<font color="#0000ff">return</font> (Counter)counts.get(s);
}
Enumeration sortedKeys() {
Enumeration e = counts.keys();
StrSortVector sv = <font color="#0000ff">new</font> StrSortVector();
<font color="#0000ff">while</font>(e.hasMoreElements())
sv.addElement((String)e.nextElement());
<font color="#009900">// This call forces a sort:</font>
<font color="#0000ff">return</font> sv.elements();
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#0000ff">try</font> {
SortedWordCount wc =
<font color="#0000ff">new</font> SortedWordCount(args[0]);
wc.countWords();
Enumeration keys = wc.sortedKeys();
<font color="#0000ff">while</font>(keys.hasMoreElements()) {
String key = (String)keys.nextElement();
System.out.println(key + ": "
+ wc.getCounter(key).read());
}
wc.cleanup();
} <font color="#0000ff">catch</font>(Exception e) {
e.printStackTrace();
}
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It
makes sense to present these in a sorted form, but since Java 1.0<A NAME="Index1173"></A>
and Java 1.1<A NAME="Index1174"></A>
don’t have any sorting methods, that will have to be mixed in. This is
easy enough to do with a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StrSortVector.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(This was created in Chapter 8, and is part of the package created in that
chapter. Remember that the starting directory for all the subdirectories in
this book must be in your class path for the program to compile successfully.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">To
open the file, a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FileInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is used, and to turn the file into words a
<a name="StreamTokenizer"></a></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StreamTokenizer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is created from the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FileInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StreamTokenizer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
there is a default list of separators, and you can add more with a set of
methods. Here,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ordinaryChar( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is used to say “This character has no significance that I’m
interested in,” so the parser doesn’t include it as part of any of
the words that it creates. For example, saying
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>st.ordinaryChar('.')</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
means that periods will not be included as parts of the words that are parsed.
You can find more information in the online documentation that comes with Java.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>countWords( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
the tokens are pulled one at a time from the stream, and the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ttype</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
information is used to determine what to do with each token, since a token can
be an end-of-line, a number, a string, or a single character.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Once
a token is found, the <A NAME="Index1175"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable
counts
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is queried to see if it already contains the token as a key. If it does, the
corresponding
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Counter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object is incremented to indicate that another instance of this word has been
found. If not, a new
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Counter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is created – since the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Counter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor initializes its value to one, this also acts to count the word.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SortedWordCount</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is not a type of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so it wasn’t inherited. It performs a specific type of functionality, so
even though the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>keys( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>values( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods must be re-exposed, that still doesn’t mean that <A NAME="Index1176"></A><A NAME="Index1177"></A>inheritance
should be used since a number of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods are inappropriate here. In addition, other methods like
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getCounter( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -