Java使用Scanner读取CSV文件时内容开头出现问号如何解决
问题原因
读取结果开头的问号是*UTF-8 BOM(字节顺序标记)*导致的。Windows下很多文本编辑器保存UTF-8文件时,会在文件最开头插入3字节的BOM头(0xEF 0xBB 0xBF)标记编码。你当前代码创建Scanner时没有指定读取编码,默认用运行平台的字符集解析文件,无法识别BOM头,会将其解析为特殊字符,输出时就显示为问号。
原有问题代码
public void vulNamenLijst() { // TODO: Lees het bestand "resources/NamenlijstGroot.csv" en zet elke regel (<tussenvoegsel>,<achternaam>) // in de ArrayList namenLijst. file = new File("resources/NamenlijstGroot.csv"); try ( Scanner scanner = new Scanner(file); ) { while (scanner.hasNext()) { String line = scanner.nextLine(); String[] values = line.split(","); String namePrefix = values[0]; String surname = values[1]; namenLijst.add(namePrefix + " " + surname); } } catch (FileNotFoundException e) { System.err.println("Data file doesn't exist!"); } catch (Exception e) { System.err.println("Something went wrong"); e.printStackTrace(); } }
修复方法
- 先导入标准字符集类:
import java.nio.charset.StandardCharsets; - 初始化
Scanner时显式指定用UTF-8编码读取文件 - 读取每行内容后,移除开头可能存在的BOM字符(UTF-8解码后BOM对应Unicode字符
\uFEFF)
修复后的读取逻辑代码:
try ( // 显式指定UTF-8编码构造Scanner Scanner scanner = new Scanner(file, StandardCharsets.UTF_8); ) { while (scanner.hasNext()) { String line = scanner.nextLine(); // 清除开头可能存在的BOM标记 if (line.startsWith("\uFEFF")) { line = line.substring(1); } String[] values = line.split(","); String namePrefix = values[0]; String surname = values[1]; namenLijst.add(namePrefix + " " + surname); } }
也可以不修改代码,直接用文本编辑器打开CSV文件,另存为UTF-8 无BOM编码覆盖原文件,同样能解决问题。但代码层面做兼容适配鲁棒性更高,后续更换带BOM的输入文件也不会复现该问题。
参考截图
- 异常读取结果:

- 原始CSV文件内容:

练习所用项目框架地址:https://github.com/Remzi1993/klantenBestand
内容的提问来源于stack exchange,提问作者Remzi Cavdar
相关产品推荐
相关产品推荐

