在 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 进行关闭。