使用Scanner读取整数文件失败,文件出现莫名开头问号
问题解决:Scanner无法读取含隐藏BOM的整数文件
问题根源
你看到的开头问号其实是UTF-8编码的BOM(字节顺序标记),它是文件开头的隐藏字节序列(EF BB BF),普通编辑器不会显示,但会被当成非数字字符,导致Scanner.hasNextInt()直接返回false,无法读取后续的整数。
解决方案
方案1:读取时跳过开头的非数字字符(快速解决)
在循环读取整数前,先跳过所有非数字的前置字符,修改代码如下:
case POPULATION: try { // 跳过开头所有非数字字符(包括BOM) sc.skip("[^0-9]*"); while (sc.hasNextInt()) { int num = sc.nextInt(); this.listePops.add(num); // 可选:打印验证 System.out.println(num); } } catch (Exception e) { System.err.println("~ERREUR~ : " + e.getMessage()); } break;
[^0-9]*表示匹配任意数量的非数字字符,能精准跳过开头的BOM或其他无效字符。
方案2:手动跳过BOM字节(原生Java实现)
如果需要更精准处理BOM,可以直接从输入流层面跳过:
case POPULATION: try { FileInputStream fis = new FileInputStream("你的文件路径"); // 检查并跳过UTF-8 BOM(EF BB BF) byte[] bom = new byte[3]; if (fis.read(bom) != -1 && !(bom[0] == (byte)0xEF && bom[1] == (byte)0xBB && bom[2] == (byte)0xBF)) { // 如果不是BOM,把读出来的字节放回去 fis.reset(); } Scanner sc = new Scanner(fis); while (sc.hasNextInt()) { this.listePops.add(sc.nextInt()); } sc.close(); fis.close(); } catch (Exception e) { System.err.println("~ERREUR~ : " + e.getMessage()); } break;
方案3:重新保存文件去除BOM(如果允许修改文件)
用专业文本编辑器(如Notepad++)打开文件,选择「编码」→「UTF-8 无BOM」,然后重新保存,这样文件就不会有隐藏的BOM标记,原代码就能正常读取。
内容的提问来源于stack exchange,提问作者mi1000
相关产品推荐
相关产品推荐

