Java 两个版本的扫描仪之间有什么区别?

Java 两个版本的扫描仪之间有什么区别?,java,input,console,Java,Input,Console,从控制台读取输入的这些方法之间有什么区别 Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in))); 及 那么优点和缺点是什么?我认为回答这些问题的最好方法是检查实际实现的来源。您可以从这里下载源代码:或者只下载特定于Google的类:“java.util.Scanner source” 在这种情况下,匹配源: public Scanner(InputStream source) { th

从控制台读取输入的这些方法之间有什么区别

Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));


那么优点和缺点是什么?

我认为回答这些问题的最好方法是检查实际实现的来源。您可以从这里下载源代码:或者只下载特定于Google的类:“java.util.Scanner source”

在这种情况下,匹配源:

public Scanner(InputStream source) {
   this(new InputStreamReader(source), WHITESPACE_PATTERN);
}
您可以使用此代码段实现相同的功能:

Scanner in = new Scanner(new BufferedReader(new InputStreamReader(new BufferedInputStream(System.in))));
扫描仪
构造函数 就目前的情况来看,两者没有太大区别

您使用的
Scanner
的第一个构造函数
Scanner(Readable)
,将表示字符传入序列的对象作为参数,可以使用
字符缓冲区
读取该序列

您使用的
Scanner
的第二个构造函数是
Scanner(InputStream)
,它将表示传入的字节序列的对象作为参数

应该强调的是,字节不是字符。字符可以由不同的字节序列表示,具体取决于字符编码,并且每个字符可以跨越一个以上的字节

在内部,第二个构造函数立即用
InputStreamReader
包装参数,这是一个提供字符数据的
可读的
,因此与使用第一个构造函数几乎相同

BufferedInputStream
vs
BufferedReader
因此,仍然存在的差异是

new BufferedReader(new InputStreamReader(System.in))

它们读取数据的方式略有不同

第一个链将在每次需要输入时填充8192个字符的缓冲区,从底层读卡器获取每个字符,该读卡器将从
System.in
的字节中对其进行解释

第二个链将在每次需要输入时填充8192字节的缓冲区。因此,当包装读取器需要下一个字符时,假设该字符在输入中由两个字节表示,而当前缓冲区中只有该字符的一个字节。第二个字节将需要再次填充缓冲区

我没有经验数据,但我认为,考虑到
扫描器
每次需要数据时都会填充
字符缓冲区
,上述细微差别将是相当微不足道的。事实上,我相信您可以安全地放弃使用
BufferedReader
BufferedInputStream
,只需将
InputStreamReader
系统直接送入
扫描仪,它将负责缓冲

指定输入的字符集 如果需要使用特定的字符集进行输入,则会有所不同。例如,如果要确保传入的字节流被解释为
UTF-8
,可以使用:

Scanner in = new Scanner(new InputStreamReader(System.in,StandardCharsets.UTF_8));
否则,输入字节将被解释为默认字符集,该字符集不一定是
UTF-8

扫描器
还有另一个构造函数,它也允许使用普通的
输入流

Scanner in = new Scanner(System.in, "UTF-8");

这也将包装
系统。在
中,立即使用
InputStreamReader
,因此差别不大。

扫描仪
只有1024个字符的缓冲区,添加一个
缓冲区…
会添加8192个字符/字节的底层缓冲区。因此,如果您正在读取大量数据(例如文件),这是有区别的,但我认为如果您正在读取较小的输入(例如控制台输入),则没有优势
Scanner in = new Scanner(new InputStreamReader(System.in,StandardCharsets.UTF_8));
Scanner in = new Scanner(System.in, "UTF-8");