Java读取文件数字求和抛出NumberFormatException空串解析异常排查
异常产生原因
异常的核心诱因是BufferedReader的重复读取逻辑错误:
- 你在
while(s1.readLine()!=null)的判断条件中,已经执行了一次读行操作,这一次读取到的内容没有被保存,直接被丢弃了。 - 当判断结果为非空、进入循环体后,你又第二次调用
s1.readLine()读取下一行内容。如果文件的总行数是奇数,或者第二次读取刚好触碰到文件末尾,这次调用会返回null,后续把null传入Integer.parseInt()做类型转换,就会抛出Cannot parse null string的NumberFormatException。
这种重复读取的逻辑哪怕不触发空转换异常,也会直接丢失奇数行的内容,最终计算的总和结果完全错误。
除此之外原代码还有两个潜在问题:
- 流关闭操作写在try块内,一旦读文件过程中抛出异常,
s1.close()不会执行,会造成文件资源泄漏 - catch块只捕获IOException,没有处理行内容不是合法数字、存在空行的场景,遇到异常格式内容也会抛转换异常
修正方案
核心是修正循环读逻辑,保证每次循环只调用一次readLine(),推荐用Java 7开始支持的try-with-resources语法自动管理流资源,避免手动关流的疏漏,同时增加基础的格式校验提升鲁棒性。
修正后可运行代码如下:
int sum = 0; // try-with-resources会在代码块执行结束后自动关闭流,不需要手动调用close try ( FileReader f1 = new FileReader("E:\\Java_Examples\\data.txt"); BufferedReader s1 = new BufferedReader(f1) ) { String line; // 单次读取,把读取结果直接赋值给line再判断非空,不会重复读行、丢失内容 while ((line = s1.readLine()) != null) { // 跳过空行避免转换报错 if (line.isBlank()) { continue; } sum += Integer.parseInt(line.trim()); } System.out.println("文件内数字总和为:" + sum); } catch (IOException e) { System.out.println("文件读取失败:" + e.getMessage()); } catch (NumberFormatException e) { System.out.println("文件内存在非数字内容,转换失败:" + e.getMessage()); }
如果不使用try-with-resources语法,也要把流关闭逻辑放到finally块中保证一定会执行,核心循环的单次读取逻辑不能写错。
内容的提问来源于stack exchange,提问作者Abdul Salam Ghanghro
相关产品推荐
相关产品推荐

