读取非空TXT文件时Scanner的hasNext()始终返回false问题求助
问题分析与解决方案
你遇到的问题核心是字符编码不匹配导致Scanner无法正确解析俄文文本文件,所以hasNext()一直返回false。Scanner默认使用系统平台的默认编码(比如Windows下是GBK),而你的俄文文件大概率是用UTF-8或者Windows-1251(俄语常用编码)保存的,编码不兼容就会让Scanner误以为文件是空的。
修复步骤
1. 指定Scanner的字符编码
创建Scanner时明确指定文件的编码格式,比如如果是UTF-8编码:
Scanner input = new Scanner(file, "UTF-8");
如果是Windows-1251编码(俄罗斯常用的本地编码),就改成:
Scanner input = new Scanner(file, "Windows-1251");
你可以先试UTF-8,如果不行再换Windows-1251,一般这两个其中一个能解决编码问题。
2. 修正空内容判断逻辑
你代码里if(!input.hasNext())的判断时机不对——哪怕文件内容被正常读取完,这个条件也会成立,导致每次都打开文件。应该改成判断currentSong是否为空,只有当确实没读到内容时才打开文件:
if(currentSong.length() == 0) { Desktop d = Desktop.getDesktop(); d.open(file); }
3. 用try-with-resources自动管理资源
为了避免资源泄漏(比如Scanner或PrintWriter没正确关闭),推荐使用Java 7+的try-with-resources语法,它会自动关闭实现了AutoCloseable的资源:
try (Scanner input = new Scanner(file, "UTF-8"); PrintWriter write = new PrintWriter("new/" + i + ".txt")) { while(input.hasNextLine()) { // 用hasNextLine()更贴合你读取行的逻辑 currentSong.append(input.nextLine()); } if(currentSong.length() == 0) { Desktop d = Desktop.getDesktop(); d.open(file); } write.write(currentSong.toString()); } // 这里会自动关闭input和write
完整修正后的代码片段
for(int i = 1; i <= 126; i++) { StringBuilder currentSong = new StringBuilder(); try { String name = i + ".txt"; File file = new File(name); if(file.exists()) { // 使用try-with-resources管理Scanner和PrintWriter try (Scanner input = new Scanner(file, "UTF-8"); PrintWriter write = new PrintWriter("new/" + i + ".txt")) { // 用hasNextLine()更适合逐行读取的场景 while(input.hasNextLine()) { currentSong.append(input.nextLine()); } // 只有当没读到内容时才打开文件 if(currentSong.length() == 0) { Desktop d = Desktop.getDesktop(); d.open(file); } write.write(currentSong.toString()); } } else { JOptionPane.showMessageDialog(null, "No file was found"); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } }
额外提示
如果不确定文件的编码,可以用Notepad++打开文件,查看右下角显示的编码格式,然后对应到代码里的编码字符串即可。
内容的提问来源于stack exchange,提问作者Eddie
相关产品推荐
相关产品推荐

