BufferedReader读取控制台字符打印出现额外空行的原因咨询
问题原因
核心是两个机制共同作用的结果:
- 控制台默认采用行缓冲模式:你在键盘敲入的所有字符,会暂时存在控制台的缓冲区里,不会立刻发送给Java程序,只有当你按下回车键时,整行内容才会被推送到程序的输入流中。而按下回车这个动作本身,会自动向输入流追加行结束控制字符(Windows系统下是
\r回车符+\n换行符两个不可见字符,Linux/macOS下是\n一个字符)。 - 你的循环退出逻辑是「读到字符→打印字符→判断是不是q,是就立刻退出」。
两个测试场景的输出差异可以对应解释:
- 输入
testq的场景:你输完testq后按回车,整行内容送入流中,程序按顺序读取t、e、s、t、q,每读一个就打印一个。读到q并打印后,循环判断条件不满足,直接终止程序运行。回车动作追加的行结束控制字符还没来得及被读取,程序就已经退出了,自然不会产生额外空行。 - 输入
test(不含q)的场景:你输完test按回车后,程序读完t、e、s、t四个可见字符,因为没碰到q,不会退出循环,会继续读取后面跟着的所有行结束控制字符。这些控制字符本身是不可见的,而println方法每打印一个字符就会自动追加一个换行,打印不可见控制字符时就会表现为输出空行。你观察到的4个空行,本质是程序持续读取到了后续输入(包括你第一次按回车产生的控制符、以及后续为了确认程序状态按下的回车产生的控制符)并逐字符打印的结果——只要你一直不输入q,程序会一直阻塞等待新的输入,把所有读到的字符(包括回车这类不可见字符)都打印出来。
优化方案
如果不需要打印回车、换行这类不可见控制字符,可以在读取后增加过滤逻辑再打印:
do { ch = (char) br.read(); // 过滤回车、换行控制符 if (ch != '\r' && ch != '\n') { System.out.println(ch); } } while (ch != 'q');
内容的提问来源于stack exchange,提问作者Shri
相关产品推荐
相关产品推荐

