scanner类配合io流可高效解析结构化文本,需选择合适数据源、设置分隔符、预判类型并处理边界;支持字符串和文件输入,推荐try-with-resources管理资源,灵活配置正则分隔符,安全读取需配合hasnextxxx()及缓冲清理。
scanner类配合io流能高效解析文本变量,关键在于选择合适的数据源、设置合理分隔规则,并注意类型读取与边界处理。它不是万能解析器,但对结构清晰的文本(如空格/逗号分隔、固定字段顺序)非常直接有效。
从字符串或文件流创建Scanner实例
文本变量常以String或File形式存在,Scanner支持直接封装:
- 解析字符串:用new Scanner("name 25 city"),适合测试、配置项提取或日志片段处理
- 读取文件:用new Scanner(new File("data.txt")),建议加字符集参数防乱码,例如new Scanner(new File("data.txt"), "UTF-8")
- 配合try-with-resources自动释放资源,避免IO泄漏:try (Scanner sc = new Scanner(...)) { ... }
按需调整分隔符以适配不同格式
默认以空白符(空格、换行、制表符)切分,但实际文本常含CSV、等号、竖线等分隔方式:
- 逗号分隔(含空格):sc.useDelimiter("\s*,\s*"),正则中双反斜杠是Java字符串转义要求
- 键值对(如user=alice):sc.useDelimiter("\s*=\s*|\s+"); 同时匹配等号和空白分隔
- 日志时间戳后的内容提取:先sc.skip("\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\s*");跳过开头,再读取剩余字段
安全读取与类型转换的实操要点
避免InputMismatchException和NoSuchElementException是日常高频问题:
- 读数字前务必用hasNextInt()、hasNextDouble()预判,而不是直接调nextInt()
- next()只读到下一个空白符,nextLine()才读整行;混合使用时,nextInt()后紧跟nextLine()会“吞掉”回车,应补一个sc.nextLine()清空缓冲
- 提取特定模式内容可用findInLine("ERROR:\d+"),返回匹配字符串或null,比手动截取更鲁棒
典型场景组合示例
比如解析一行CSV数据"张三, 28, 北京, true":
- 设置分隔符:sc.useDelimiter("\s*,\s*");
- 依次读取:String name = sc.next(); int age = sc.nextInt(); String city = sc.next(); boolean active = sc.nextBoolean();
- 全程用hasNextXxx()包裹,确保每步都有数据可读











