Java清除System.in中历史控制台输入:为何仅deleteInput()方法不同的两段代码效果有差异?
Java清除System.in中历史控制台输入:为何仅deleteInput()方法不同的两段代码效果有差异?
嘿兄弟,咱们先把问题拆明白——你这两段代码,除了deleteInput()方法的实现不一样,其余逻辑完全是一个模子刻出来的,而控制台输出的差异,根源绝对就在这个方法对System.in输入流的处理逻辑上。
先看你给出的代码框架:
public class DeletePreviousInputs { static Scanner scanner = new Scanner(System.in); public static void main(String[] args) throws InterruptedException, IOException { System.out.println("write something in the console"); /* * 你实际输入的内容: * 1 <enter> 2 ... */ // 这里应该会调用deleteInput()方法,后续逻辑的控制台输出差异就从这来 } // 两段代码的核心区别:这个deleteInput()的实现不同 }
咱得先搞懂System.in的脾气——它是个字节输入流,你在控制台敲的每一个字符(包括回车对应的\r和\n)都会暂存在它的缓冲区里。deleteInput()就是用来清这个缓冲区的,实现不一样,清的效果就天差地别:
- 比如其中一个版本可能只调用了
scanner.nextLine(),这玩意儿只能清掉当前行的内容,要是缓冲区里还有下一行的残留字符(比如你输入1回车后又敲了2,那缓冲区里是1\r\n2,nextLine()只会清掉1\r\n,剩下的2还在),那后续代码读取的时候就直接拿这个残留的2,输出自然和另一个版本不一样; - 要是另一个版本用了
System.in.skip(System.in.available()),这就狠了——它会跳过缓冲区里所有当前可用的字节,把你之前输入的所有残留内容全清干净,后续读取就会等你新的输入,输出逻辑就正常了; - 还有可能某个版本的实现没考虑到不同系统的换行符差异(比如Windows是
\r\n,Linux是\n),导致清缓冲区的时候漏了半个换行符,后续读取时会把这个残留的控制字符当成有效输入,输出就出问题了。
总结一下:本质就是两个deleteInput()对System.in缓冲区的清理范围、清理逻辑不一样,才导致了后续控制台输出的差异,毕竟Scanner读取输入是从缓冲区拿数据的,缓冲区里剩什么,它就读什么~
备注:内容来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

