在 Java 的 I/O 处理中,java.io.StreamTokenizer 类扮演着重要角色,它能够将从 Reader 读取的字符序列进行标记化处理,从而生成一个个独立的标记。举个例子,对于字符串 “Hello, Java program”,StreamTokenizer 会把其中的每个单词都识别为一个单独的标记。
在解析文件内容或者处理计算机语言时,通常会先把输入的内容拆分成一个个标记,再进行后续的处理。这一拆分过程也被称作“词法分析(lexing)”或者“标记化处理(tokenizing)”。
借助 StreamTokenizer,你可以在底层的 Reader 中对标记进行遍历。具体的操作方式是,在一个循环里不断调用 StreamTokenizer 的 nextToken() 方法。每调用一次 nextToken() 方法,StreamTokenizer 内部就会更新几个字段,通过读取这些字段,你能够了解到当前读取的标记类型、具体值等信息。
下面为你介绍这些字段:
ttype:读取的标记类型(单词、数字、行结束符)
sval:如果标记是字符串(单词),则为该标记的字符串值
nval:如果标记是数字,则为该标记的数值。
以下是一个简单的 StreamTokenizer 示例:
package com.hxstrive.java_io;
import java.io.StreamTokenizer;
import java.io.StringReader;
public class StreamTokenizerExample {
public static void main(String[] args) throws Exception {
StreamTokenizer streamTokenizer = new StreamTokenizer(
new StringReader("Hello, Java program 1+1=2"));
while(streamTokenizer.nextToken() != StreamTokenizer.TT_EOF){
if(streamTokenizer.ttype == StreamTokenizer.TT_WORD) {
// 读取的内容是单词
System.out.println("sval=" + streamTokenizer.sval);
} else if(streamTokenizer.ttype == StreamTokenizer.TT_NUMBER) {
// 读取的内容是数字
System.out.println("nval=" + streamTokenizer.nval);
} else if(streamTokenizer.ttype == StreamTokenizer.TT_EOL) {
// 已读取到行尾
System.out.println();
} else {
// 处理其他字符标记
System.out.println("other=" + (char)streamTokenizer.ttype);
}
}
}
}输出结果:
sval=Hello other=, sval=Java sval=program nval=1.0 other=+ nval=1.0 other== nval=2.0
注意:StreamTokenizer 能够识别标识符、数字、带引号字符串和各种注释样式。您还可以指定将哪些字符解释为空白、注释开始和结束等。在开始解析 StreamTokenizer 内容之前,所有这些都要在 StreamTokenizer 上进行配置。
StreamTokenizer 没有继承任何类,仅仅是一个工具类,因此使用完毕不需要关闭,而且也没有关闭的 close() 方法,如下图:

但是,如果你传递给 StreamTokenizer 的 Reader 是一个使用了文件资源或网络资源的 Reader,则需要负责将该 Reader 进行关闭。