从控制台读取输入的这些方法之间有什么区别?
Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
和
Scanner in = new Scanner(new BufferedInputStream(System.in));
有哪些优点和缺点?
答案 0 :(得分:1)
Scanner
构造函数正如这些电话所说的那样,没有多大区别。
您使用的Scanner
的第一个构造函数Scanner(Readable)
将一个表示字符的传入序列的对象作为参数,可以使用{{ 1}}。
您使用的CharBuffer
的第二个构造函数Scanner
将一个对象作为参数,该对象表示字节的传入序列。
应该强调的是,字节不是字符。字符可以由不同的字节序列表示,具体取决于字符编码,并且每个字节可以跨越多个字节。
在内部,第二个构造函数立即用Scanner(InputStream)
包装参数 - 这是一个提供字符数据的InputStreamReader
,因此它与使用第一个构造函数几乎相同。
Readable
vs BufferedInputStream
所以剩下的差异是
之间的差异BufferedReader
和
new BufferedReader(new InputStreamReader(System.in))
这些数据在读取数据方面略有不同。
每次需要输入时,第一个链将填充8192个字符的缓冲区,从底层读取器获取每个字符,从new InputStreamReader(new BufferedInputStream(System.in));
的字节开始解释它。 / p>
每次需要输入时,第二个链将填充8192 字节的缓冲区。因此,当包装阅读器需要下一个字符时,假设该字符在输入中由两个字节表示,并且该字符中只有一个字节在当前缓冲区中。第二个字节需要另一个缓冲区填充。
我没有经验数据,但我认为,只要System.in
每次需要数据时填充Scanner
,上述细微差别就会变得微不足道。事实上,我相信您可以安全地放弃使用CharBuffer
或BufferedReader
,只需将BufferedInputStream
或InputStreamReader
直接提供给System.in
即可照顾缓冲。
如果你需要为输入使用特定的字符集,会会有所不同。例如,如果您想确保传入的字节流被解释为Scanner
,您可以使用:
UTF-8
否则,输入字节将在您的默认字符集中解释,该字符集可能不一定是Scanner in = new Scanner(new InputStreamReader(System.in,StandardCharsets.UTF_8));
。
UTF-8
还有另一个构造函数,它也允许使用普通Scanner
:
InputStream
这也会立即用Scanner in = new Scanner(System.in, "UTF-8");
包裹System.in
,所以差别不大。
答案 1 :(得分:0)
我认为回答这些问题的最佳方法是检查实际实施的来源。您可以从此处下载源:http://download.java.net/openjdk/jdk8/或仅限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))));