博主18年的互联网软件开发经验,从一名程序员小白逐步成为了一名架构师,我想通过平台将经验分享给大家,因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验,晚上进行用心精简、整理、总结、定稿,每天都会整理到12点,为了就是能让大家能够真正了解该技术栈的真正原理,最终从程序员成为一名真正的架构师,写的不一定是全站做好的,但是是全站最用心的~。
以后我会推出一些列的文章,每天都会更新,每天进步一点点,发布顺序【java的api基础、应用、实战】->【java开源技术栈及源码分析】->【java开源技术栈整合】->【java低代码开发平台的建设】
关注【架构师成长之道】 输入“java基础课程”,即可免费获得全套架构师全套课程
一、java.io
1.70 StreamTokenizer
基本概念
StreamTokenizer
类用于将输入流解析为标记(tokens),例如数字、字符串和特殊字符。它是一个强大的工具,常用于分析简单的文本数据,例如配置文件、日志文件等。以下是关于 StreamTokenizer
的介绍、属性、构造方法、方法以及一个简单的例子:
介绍:
-
StreamTokenizer
类允许将输入流(Reader
对象)解析为标记(tokens),并允许以不同的方式处理这些标记。
属性:
-
nval
:包含当前标记的数值(如果当前标记是数字),否则为 0.0。 -
sval
:包含当前标记的字符串值(如果当前标记是字符串),否则为null
。 -
ttype
:指示当前标记的类型。可能的值有:TT_EOF
(-1,表示输入流的末尾)、TT_EOL
(10,表示换行符)、TT_NUMBER
(表示一个数字)、TT_WORD
(表示一个单词)以及具体的字符值(例如','
)。
构造方法:
-
StreamTokenizer(Reader r)
:创建一个新的StreamTokenizer
对象,使用指定的Reader
对象作为输入流。
方法:
-
nextToken()
:读取下一个标记并返回其类型。 -
ordinaryChar(int ch)
:指定字符ch
为“普通字符”,即不被视为分隔符。 -
resetSyntax()
:将当前的语法设置为默认设置。 -
等等,还有其他方法用于设置和获取解析器的各种属性。
简单的例子:
以下是一个简单的例子,演示了如何使用 StreamTokenizer
来解析一段文本并提取数字和单词:
javaCopy code import java.io.*; public class StreamTokenizerExample { public static void main(String[] args) { String text = "The quick brown fox jumps over 123 the lazy dog."; try { // 创建输入流 StringReader stringReader = new StringReader(text); StreamTokenizer tokenizer = new StreamTokenizer(stringReader); // 设置特定字符为普通字符,不被视为分隔符 tokenizer.ordinaryChar('.'); // 解析文本并提取标记 while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { switch (tokenizer.ttype) { case StreamTokenizer.TT_NUMBER: System.out.println("数字:" + tokenizer.nval); break; case StreamTokenizer.TT_WORD: System.out.println("单词:" + tokenizer.sval); break; default: // 其他字符(如标点符号)或换行符 if (tokenizer.ttype == '\n') { System.out.println("换行符"); } else { System.out.println("其他字符:" + (char) tokenizer.ttype); } break; } } } catch (IOException e) { e.printStackTrace(); } } }
在这个例子中,我们创建了一个 StreamTokenizer
对象,将一段文本传递给它进行解析。然后,我们使用 nextToken()
方法逐个读取标记,并根据标记的类型进行处理。如果标记是数字,我们输出其数值;如果是单词,我们输出其字符串值;如果是其他字符(如标点符号)或换行符,则作出相应的处理。
应用场景
StreamTokenizer
在处理文本数据时非常有用。以下是一些常见的应用场景及其对应的代码实现:
-
简单文本解析: 可以使用
StreamTokenizer
对文本进行简单的解析,提取其中的数字、单词和特殊字符。
javaCopy code import java.io.*; public class SimpleTextParsing { public static void main(String[] args) { String text = "The price of the product is $25.50 and the discount is 10%."; try { StringReader stringReader = new StringReader(text); StreamTokenizer tokenizer = new StreamTokenizer(stringReader); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == StreamTokenizer.TT_WORD) { System.out.println("单词:" + tokenizer.sval); } else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) { System.out.println("数字:" + tokenizer.nval); } else { System.out.println("其他字符:" + (char) tokenizer.ttype); } } } catch (IOException e) { e.printStackTrace(); } } }
2.配置文件解析: 可以使用 StreamTokenizer
解析简单的配置文件,提取其中的配置项和对应的值。
javaCopy code import java.io.*; public class ConfigFileParsing { public static void main(String[] args) { try { FileReader fileReader = new FileReader("config.txt"); StreamTokenizer tokenizer = new StreamTokenizer(fileReader); while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == StreamTokenizer.TT_WORD) { String key = tokenizer.sval; tokenizer.nextToken(); // 读取等号 if (tokenizer.ttype == '=') { tokenizer.nextToken(); // 读取值 String value = tokenizer.sval; System.out.println("配置项:" + key + ", 值:" + value); } } } } catch (IOException e) { e.printStackTrace(); } } }
3.词法分析器: 可以使用 StreamTokenizer
编写简单的词法分析器,将源代码分解为标记,并进行进一步的处理。
javaCopy code import java.io.*; public class LexicalAnalyzer { public static void main(String[] args) { String sourceCode = "int a = 10; float b = 20.5;"; try { StringReader stringReader = new StringReader(sourceCode); StreamTokenizer tokenizer = new StreamTokenizer(stringReader); tokenizer.parseNumbers(); // 允许解析数字 tokenizer.wordChars('_', '_'); // 允许下划线在单词中出现 while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { switch (tokenizer.ttype) { case StreamTokenizer.TT_WORD: System.out.println("单词:" + tokenizer.sval); break; case StreamTokenizer.TT_NUMBER: System.out.println("数字:" + tokenizer.nval); break; case '=': System.out.println("赋值符号"); break; case ';': System.out.println("分号"); break; default: System.out.println("其他字符:" + (char) tokenizer.ttype); break; } } } catch (IOException e) { e.printStackTrace(); } } }
在这些示例中,我们演示了 StreamTokenizer
的不同应用场景,包括简单文本解析、配置文件解析和词法分析器。StreamTokenizer
提供了一种简单而灵活的方法来处理文本数据,并根据需要提取所需的信息。
实战例子
以下是一个项目实战示例,展示了如何使用 StreamTokenizer
解析一个简单的配置文件,并根据配置文件的内容执行相应的操作。
假设我们有一个名为 ConfigParser
的类,它负责解析配置文件,并根据配置执行不同的操作。配置文件的格式如下:
Copy code database.host=localhost database.port=3306 database.user=admin database.password=123456
我们将解析这个配置文件,然后连接到数据库并执行一些操作。
javaCopy code import java.io.*; import java.util.*; public class ConfigParser { private String host; private int port; private String user; private String password; public ConfigParser(String filePath) { try { parseConfig(filePath); } catch (IOException e) { System.err.println("无法读取配置文件:" + e.getMessage()); } } private void parseConfig(String filePath) throws IOException { FileReader fileReader = new FileReader(filePath); StreamTokenizer tokenizer = new StreamTokenizer(fileReader); tokenizer.wordChars('.', '.'); // 允许点号在单词中出现 tokenizer.parseNumbers(); // 允许解析数字 Map<String, String> configMap = new HashMap<>(); String key = null; String value = null; while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { if (tokenizer.ttype == StreamTokenizer.TT_WORD) { key = tokenizer.sval; } else if (tokenizer.ttype == '=') { tokenizer.nextToken(); // 读取值 value = tokenizer.sval; configMap.put(key, value); } } this.host = configMap.get("database.host"); this.port = Integer.parseInt(configMap.get("database.port")); this.user = configMap.get("database.user"); this.password = configMap.get("database.password"); } public void connectToDatabase() { System.out.println("连接到数据库:"); System.out.println("主机:" + host); System.out.println("端口:" + port); System.out.println("用户:" + user); System.out.println("密码:" + password); // 在此处执行数据库连接操作 } public static void main(String[] args) { ConfigParser parser = new ConfigParser("config.txt"); parser.connectToDatabase(); } }
在这个示例中,我们首先定义了一个 ConfigParser
类,它有一个构造方法,用于接收配置文件的路径并解析该文件。然后,我们使用 StreamTokenizer
解析配置文件,并将键值对存储在 configMap
中。最后,我们根据配置文件中的信息连接到数据库,并输出连接信息。
假设 config.txt
文件的内容如下:
Copy code database.host=localhost database.port=3306 database.user=admin database.password=123456
当我们运行 main
方法时,将输出连接到数据库的相关信息。