Java中Scanner读取文本并用StringBuffer拼接时内容丢失问题求助
Scanner读取文件时前四行内容丢失的原因分析与解决办法
问题重现
使用Scanner读取本地test.txt文件,设置分隔符为\n,通过StringBuffer拼接内容时,前四行文本丢失,仅最后一行正常显示,循环执行了5次。但注释掉str.append("//")语句后,程序运行正常。
测试文本内容:
hello a hello b hello c hello d hello e
原代码:
import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; public class Learn01 { public static void main(String[] args) { Scanner scanner = null; try { scanner = new Scanner(new File("d:" + File.separator + "test.txt")); scanner.useDelimiter("\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } int flag =0; StringBuffer str = new StringBuffer(); while (scanner.hasNext()) { str.append(scanner.next()); str.append("//"); str.append("\n"); flag++; } System.out.println(str); System.out.println("finish"); System.out.println(flag); } }
运行结果:
// // // // hello e// finish 5
原因分析
问题核心在于换行符的系统差异:
- Windows系统下的文本文件换行符是
\r\n(回车+换行),但你设置Scanner的分隔符为\n,导致scanner.next()读取到的每行内容末尾会带有\r字符(比如第一行实际读取的是"hello a\r")。 - 当拼接
"hello a\r"和"//"后,输出时\r会将光标移到当前行开头,后续的//会直接覆盖掉前面的hello a,所以看起来前四行只有//。 - 最后一行
hello e如果没有末尾的换行符,就不会带有\r,因此不会被覆盖,能正常显示。
解决办法
有两种可行的修复方式:
1. 适配系统标准换行符作为分隔符
用System.lineSeparator()获取当前系统的标准换行符,替换硬编码的\n:
scanner.useDelimiter(System.lineSeparator());
2. 读取时去除回车控制字符
在读取后对字符串做处理,去掉多余的\r:
str.append(scanner.next().replace("\r", ""));
修改后的代码示例(以第一种方法为例):
import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; public class Learn01 { public static void main(String[] args) { Scanner scanner = null; try { scanner = new Scanner(new File("d:" + File.separator + "test.txt")); // 使用系统标准换行符作为分隔符 scanner.useDelimiter(System.lineSeparator()); } catch (FileNotFoundException e) { e.printStackTrace(); } int flag =0; StringBuffer str = new StringBuffer(); while (scanner.hasNext()) { str.append(scanner.next()); str.append("//"); str.append("\n"); flag++; } System.out.println(str); System.out.println("finish"); System.out.println(flag); } }
运行后即可正常显示所有行的内容。
内容的提问来源于stack exchange,提问作者jack peng
相关产品推荐
相关产品推荐

