跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何使用 Java Scanner 正确读取文件中的数字并求和

本文详解 scanner 读取文件数字时的常见误区,重点说明为何 `new scanner(path)` 无法直接替代 `new scanner(new file(path))`,并提供健壮、简洁、符合最佳实践的实现方案。 在 Java 中,Scanner 构造函数接受多种输入源(InputStream、Readable、File、Path、甚至 String),但 传入字符串路径(如 "data.txt")与传入 File 对象有本质区别 : ✅ new Scanner(new File("data.txt")):将 File 对象作为数据源,Scanner 会尝试打开该文件并读取其内容; ❌ new Scanner("data.txt"):将字符串 "data.txt" 本身作为待解析的文本内容——Scanner 不会打开文件,而是直接对这个 8 字符字符串进行扫描,因此 hasNextInt() 永远返回 false,循环不执行,结果恒为 0。 ? 补充说明:Java 7+ 确实支持 new Scanner(Paths.get("data.txt"))(需传入 java.nio.file.Path 对象),但这与直接传 String 路径完全不同。Scanner(String) 构造器仅用于解析内存中的字符串字面量。 以下是 推荐的、健壮且简洁的实现方式 (使用 try-with-resources + Path + Files.newInputStream(),兼容现代 Java 最佳实践):
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; public class SumNumbers { public static void main(String[] args) throws IOException { // 委托异常,避免空 catch String path = "numbers.txt"; int sum = 0; try (Scanner s = new Scanner(Files.newInputStream(Paths.get(path)))) { while (s.hasNext()) { // 关键:不再用 hasNextInt() 控制循环 if (s.hasNextInt()) { sum += s.nextInt(); } else { s.next(); // 跳过非数字 token(如字母、符号、空行) } } } System.out.println("Sum: " + sum); } }
✅ 关键改进点说明: 循环条件改为 while (s.hasNext()) :确保遍历所有 token,再逐个判断是否为整数; 移除冗余的 if (s.hasNextInt()) 判断 :原代码中 while 已保证进入循环时 hasNextInt() 为真,内层 if 完全多余; 异常处理升级为 throws IOException :避免吞掉关键错误信息(如文件不存在、权限不足、 编码 异常),便于调试与维护; 优先使用 Paths.get() + Files.newInputStream() :比 new File(path) 更现代、更安全(自动处理路径分隔符、支持符号链接等),且明确表达“以文件内容为输入源”的语义。 ⚠️ 注意事项: Trae win Trae Windows 官方版本现已全面支持 Win10 和 Win11 系统(64位)。国内开发者可直接访问 Trae 中文官网(trae.cn 或 trae.com.cn),一键下载官方正版 .exe 安装包,享受国内直连的高速稳定体验。安装过程极其简便,双击即可运行,并支持一键无缝导入 VS Code 或 Cursor 的原有主题、快捷键及插件配置。登录支持手机号、微信或稀土掘金账号。内置免费的豆包与 DeepSeek 等顶级大模型,让你开箱即用,轻松开启高效的 AI 智能编程之旅。 下载 立即学习 “ Java免费学习笔记(深入) ”; 若文件包含浮点数(如 3.14)、负数(如 -42)或十六进制数(如 0xFF),hasNextInt() 会跳过它们;如需支持,可改用 hasNextDouble() 或结合正则校验; Scanner 默认使用空白符(空格、制表符、换行)分隔 token,无需额外处理换行; 避免在生产环境使用 throws Exception —— 应精确声明 throws IOException,体现契约清晰性。 掌握这一模式,不仅能正确求和,更能写出可读、可维护、符合 Java 生态演进方向的 I/O 代码。

相关文章