两个版本的Scanner有什么区别?

时间:2015-07-29 19:24:58

标签: java input console

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

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

Scanner in = new Scanner(new BufferedInputStream(System.in));

有哪些优点和缺点?

2 个答案:

答案 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,上述细微差别就会变得微不足道。事实上,我相信您可以安全地放弃使用CharBufferBufferedReader,只需将BufferedInputStreamInputStreamReader直接提供给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))));