【问题标题】:What are the differences between two versions of Scanner?两个版本的 Scanner 有什么区别?
【发布时间】:2015-10-20 23:05:07
【问题描述】:

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

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

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

还有什么优点和缺点?

【问题讨论】:

    标签: java input console


    【解决方案1】:

    Scanner 构造函数

    就这些电话而言,差别不大。

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

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

    需要强调的是字节不是字符。根据字符编码的不同,字符可能由不同的字节序列表示,并且每个字符可能跨越多个字节。

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

    BufferedInputStreamBufferedReader

    所以剩下的区别就是

    new BufferedReader(new InputStreamReader(System.in))
    

    new InputStreamReader(new BufferedInputStream(System.in));
    

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

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

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

    我没有经验数据,但我认为鉴于Scanner 本身每次需要数据时都会填充CharBuffer,因此上述细微差别将是微不足道的。事实上,我相信您可以放心地放弃使用BufferedReaderBufferedInputStream,而只需将InputStreamReaderSystem.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.inInputStreamReader 包装起来,所以差别不大。

    【讨论】:

    • Scanner 仅具有 1024 个字符的缓冲区,添加 Buffered... 会添加 8192 个字符/字节的底层缓冲区。因此,如果您正在读取大量数据(例如文件),则会有所不同,但是如果您正在读取较小的输入(例如控制台输入),我认为没有优势
    【解决方案2】:

    我认为回答这些问题的最佳方法是检查实际实现的来源。你可以从这里下载源代码:http://download.java.net/openjdk/jdk8/ 或者只是谷歌特定的类:“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))));
    

    【讨论】:

      猜你喜欢
      • 2020-10-10
      • 1970-01-01
      • 2019-07-15
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      相关资源
      最近更新 更多