从CSV文件读取数字时触发java.lang.NumberFormatException异常求助
排查与解决思路
咱们一步步拆解你遇到的这个NumberFormatException问题,找出原因并解决它:
首先看你给出的示例数据里有中文顿号“、”分隔不同记录,这很可能是第一个坑——行分隔符不规范。如果你的CSV文件实际是用中文顿号来分隔不同行的记录,而你直接按标准换行符读取行的话,会把多条记录当成一行,分割后得到的token可能包含中文顿号(比如0.94、9.5),这种字符串自然无法被Double.parseDouble()解析。
接下来是几个常见的排查方向和解决方法:
1. 先处理不规范的记录分隔符
如果你的文件确实用中文顿号分隔记录,那读取时需要先把每行按顿号拆分,再处理每个记录里的分号:
String line = br.readLine(); // 把每行按中文顿号拆分成独立记录 String[] records = line.split("、"); for (String record : records) { String[] tokens = record.split(";"); // 后续解析逻辑 }
2. 清理token中的隐藏字符或干扰内容
即使你觉得token是“无空格的”,也可能存在看不见的空白字符(比如制表符、换行残留)、BOM(字节顺序标记)或者其他非打印字符,这些都会导致解析失败。建议在解析前对token做清理:
// 先去除首尾空白,再过滤掉所有非数字和小数点的字符 String cleanedControl = tokens[0].trim().replaceAll("[^0-9.]", ""); String cleanedPwr = tokens[1].trim().replaceAll("[^0-9.]", ""); Double control = Double.parseDouble(cleanedControl); Double pwr = Double.parseDouble(cleanedPwr);
如果想排查到底有什么异常字符,可以打印每个字符的ASCII码:
for (char c : tokens[1].toCharArray()) { System.out.println("字符: '" + c + "' ASCII码: " + (int)c); }
比如UTF-8 BOM的ASCII码是239、187、191,要是出现这些就说明文件带BOM,需要在读取时跳过。
3. 验证分割逻辑和token长度
在解析前先确认分割后的tokens数组长度确实是3,避免因为行格式错误(比如多了分号、少了分号)导致某个token为空或内容异常:
if (tokens.length != 3) { System.err.println("格式错误的行/记录: " + record); continue; // 跳过这条错误记录,继续处理下一条 }
4. 检查文件编码
如果文件是用非UTF-8编码(比如GBK)保存的,读取时用错编码可能会导致小数点变成看起来相似但实际不同的字符,这时候解析也会失败。可以指定编码读取文件:
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("你的文件路径.csv"), "UTF-8"));
完整示例代码
把上面的逻辑整合起来,一个健壮的读取解析示例如下:
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.IOException; public class CSVNumberParser { public static void main(String[] args) { String csvPath = "your_file.csv"; try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(csvPath), "UTF-8"))) { String line; while ((line = br.readLine()) != null) { // 处理中文顿号分隔的记录 String[] records = line.split("、"); for (String record : records) { String[] tokens = record.split(";"); if (tokens.length != 3) { System.err.println("跳过格式错误的记录: " + record); continue; } try { // 清理并解析每个数值 Double control = Double.parseDouble(tokens[0].trim().replaceAll("[^0-9.]", "")); Double pwr = Double.parseDouble(tokens[1].trim().replaceAll("[^0-9.]", "")); Double thirdValue = Double.parseDouble(tokens[2].trim().replaceAll("[^0-9.]", "")); System.out.printf("解析结果: control=%.2f, pwr=%.2f, third=%.2f%n", control, pwr, thirdValue); } catch (NumberFormatException e) { System.err.println("解析记录失败: " + record); e.printStackTrace(); } } } } catch (IOException e) { e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者Adam Bemburga
相关产品推荐
相关产品推荐

