扫描仪与 BufferedReader

Scanner vs. BufferedReader

提问人:Mads Mobæk 提问时间:2/10/2010 最后编辑:Ardent CoderMads Mobæk 更新时间:6/23/2022 访问量:303642

问:

据我所知,在 Java 中从文件中读取基于字符的数据的两种最常见方法是使用 or .我还知道,通过使用缓冲区来避免物理磁盘操作,可以有效地读取文件。ScannerBufferedReaderBufferedReader

我的问题是:

  • 性能是否与?ScannerBufferedReader
  • 你为什么会选择而不是,反之亦然?ScannerBufferedReader
java 文件-io java.util.scanner bufferedreader

评论

1赞 dimo414 5/10/2010
我通常也使用 Scanner 从标准中读取('Scanner in = new Scanner(System.in)' 感觉更干净)。不确定这是否真的效率较低,但由于从 std 读取是阻塞的,我无法想象 Scanner 的效率会成为问题所在。

答:

227赞 Chandra Sekar 2/10/2010 #1

Scanner用于从流的内容中解析令牌,同时只读取流,不进行任何特殊解析。BufferedReader

事实上,你可以将 a 传递给 a 作为要解析的字符源。BufferedReaderscanner

评论

62赞 Reuben 6/14/2011
BufferedReader 是同步的,而 Scanner 不是,所以由你来决定。
1赞 ewh 5/31/2013
我知道这个话题已经很久了,但是在尝试从 Process 提供的流中吸取内容(即捕获外部命令的输出)时,我在使用 BufferedReader 的操作系统中得到了不同的结果。一旦我将代码更改为使用 Scanner,如另一个答案中所述,事情就开始一致且符合预期。
0赞 user207421 3/23/2017
@Reuben 但最终取决于其他东西的输入,这很可能是同步的。Scanner
0赞 queeg 9/3/2023
如果令牌是一行,则 BufferedReader 可以读取令牌。
226赞 BalusC 2/10/2010 #2

在当前最新的 JDK 18 版本/内部版本 (b37) 中,Scanner 的缓冲区较小(1024 个字符),而 BufferedReader8192 个字符)则更小,但绰绰有余。

至于选择,如果要解析文件,请使用 如果要逐行读取文件。另请参阅其上述链接的 API 文档的介绍性文本。ScannerBufferedReader

  • 解析 = 将给定的输入解释为标记(部分)。它能够直接将特定部分作为整数、字符串、十进制等返回给您。另请参阅类中的所有这些方法。nextXxx()Scanner
  • 阅读 = 哑流。它不断地将所有字符还给你,如果你想匹配或组合一些有用的东西,你就必须手动检查这些字符。但是,如果您无论如何都不需要这样做,那么阅读就足够了。

评论

2赞 Achow 9/7/2012
好东西。感谢您的缓冲提示。一直在寻找它,因为原生读物非常昂贵。
0赞 Asif Mushtaq 9/27/2015
@BalusC好的,我已经用过了,readFloat();等。现在知道解析的意思是什么。和 BalusC 你能给我一点时间在聊天室里 10 分钟吗,我想问一点关于缓冲,它是如何工作的。readInt();
0赞 vivek 4/16/2016
我在 Scanner 的构造函数中包装了什么?这是个好主意吗?BufferedReader
1赞 Holger 5/6/2020
Scanner的缓冲区将根据需要进行模式匹配。因此,如果你想要一个更大的缓冲区,你只需要调用,例如,在它上面,然后,它将使用一个容量为字符的缓冲区(如果它小于这个容量,则使用整个文件)。findWithinHorizon("\\z", 8192)8192
0赞 Roman 2/10/2010 #3
  1. BufferedReader 可能会为您提供更好的性能(因为 Scanner 基于 InputStreamReader,请查看源)。哎呀,用于从它使用的文件中读取数据。当我测试大文件的性能时,显示出更好的性能。nionioBufferedReadernio
  2. 要从文件中读取数据,请尝试 Apache Commons IO。
22赞 Evgeniy 4/15/2011 #4

我建议用于阅读文本。 躲起来,同时立即扔掉它。BufferedReaderScannerIOExceptionBufferedReader

82赞 Jomoos 12/11/2011 #5

请参阅此链接,以下引用自此链接:

BufferedReader 是一个简单的类,旨在有效地从 。通常,每个读取请求都像 Reader 一样 FileReader 导致发出相应的读取请求 基础流。read() 或 readLine() 的每次调用都可以 导致从文件中读取字节,将其转换为字符,以及 然后返回,这可能非常低效。效率得到提高 如果 Reader 在 BufferedReader 中被扭曲,则明显。

BufferedReader 是同步的,因此对 BufferedReader 执行读取操作 可以从多个线程安全地完成。

另一方面,扫描仪内置了更多的奶酪;它 可以执行 BufferedReader 可以执行的所有操作,并且在同一级别 效率也一样。但是,此外,扫描程序可以解析 使用常规的基元类型和字符串的基础流 表达 式。它还可以使用 您选择的分隔符。它还可以对 忽略分隔符的基础流!

然而,扫描仪不是线程安全的,它必须是外部的 同步。

选择使用 BufferedReader 还是 Scanner 取决于代码 你正在写作,如果你正在写一个简单的日志阅读器缓冲 读者就足够了。但是,如果您正在编写 XML 解析器 Scanner 是比较自然的选择。

即使在读取输入时,如果想接受用户输入行 行,然后说只需将其添加到文件中,BufferedReader 就足够了。 另一方面,如果您想接受用户输入作为命令 多个选项,然后打算执行不同的操作 根据指定的命令和选项,扫描仪将适合 更好。

评论

0赞 Pratik 9/15/2018
“另一方面,扫描仪内置了更多的奶酪;它可以完成 BufferedReader 可以做的所有事情,而且效率也相同。不同意,与 Scanner 相比,BufferedReader 的速度要快一些,因为 Scanner 解析输入数据,而 BufferedReader 只是读取字符序列。
46赞 Sujith PS 2/11/2014 #6
  1. BufferedReader具有比 Scanner 大得多的缓冲区内存。如果要从流中获取长字符串,请使用“如果要从流中分析特定类型的令牌”,请使用。BufferedReaderScanner

  2. Scanner可以使用自定义分隔符进行标记化,并将流解析为原始类型的数据,而只能读取和存储 String。BufferedReader

  3. BufferedReader是同步的,而不是。如果使用多个线程,请使用。ScannerBufferedReader

  4. Scanner隐藏 IOException,同时立即抛出它。BufferedReader

2赞 KNU 3/1/2014 #7

下面的答案取自从控制台读取:JAVA Scanner 与 BufferedReader

从控制台读取输入时,有两个选项可以实现此目的。首先使用,另一个使用 .它们都有不同的特点。这意味着如何使用它的不同。ScannerBufferedReader

Scanner将给定的输入视为标记。 只需逐行读取给定的输入作为字符串即可。 本身提供解析功能,就像 一样。BufferedReaderScannernextInt()nextFloat()

但是,其他人之间有什么区别?

  • 扫描程序将给定的输入视为令牌。BufferedReader 作为流行/字符串。
  • 使用正则表达式对给定输入进行标记化的扫描程序。使用 BufferedReader 必须编写额外的代码。
  • BufferedReaderScanner 快 *第 2 点
  • 扫描仪未同步,BufferedReader 已同步

Scanner自那以后就来了。JDK 1.5

什么时候应该使用扫描仪或缓冲阅读器?

看看它们之间的主要区别,一个使用标记化,另一个使用流线。当您需要分析功能时,请改用。但是,我更愿意.当您需要从文件中读取数据时,请使用 ,因为它在读取文件时会使用缓冲区内存,这样可以减少物理驱动器的使用。或者,您可以将其用作 的输入。ScannerBufferedReaderBufferedReaderBufferedReaderScanner

3赞 manisha mulchandani 6/16/2015 #8

在 java 中有不同的输入方式,例如:

1) BufferedReader 2) 扫描仪 3) 命令行参数

BufferedReader 从字符输入流中读取文本,缓冲字符,以便提供字符、数组和行的高效读取。

其中 Scanner 是一个简单的文本扫描器,它可以使用正则表达式解析基元类型和字符串。

如果你正在编写一个简单的日志阅读器,缓冲阅读器就足够了。如果您正在编写 XML 解析器,Scanner 是更自然的选择。

欲了解更多信息,请参阅:

http://java.meritcampus.com/t/240/Bufferedreader?tc=mm69

评论

0赞 queeg 9/3/2023
你为什么要提出命令行?然后你忘记了环境变量、配置文件、首选项 api、网络资源......
0赞 thisismydesign 11/28/2016 #9

我更喜欢,因为它不会抛出选中的异常,因此它的使用会导致代码更加简化。Scanner

9赞 Py-Coder 12/1/2016 #10

主要区别:

  1. 扫描器

  • 简单的文本扫描器,可以使用正则表达式解析基元类型和字符串。
  • Scanner 使用分隔符模式将其输入分解为标记,默认情况下,该模式与空格匹配。然后,可以使用各种 next 方法将生成的标记转换为不同类型的值。

例:

 String input = "1 fish 2 fish red fish blue fish";
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());
 s.close(); 

打印以下输出:

1
2
red
blue

可以使用以下代码生成相同的输出,该代码使用正则表达式一次解析所有四个标记:

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input);
 s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 MatchResult result = s.match();
 for (int i = 1; i <= result.groupCount(); i++) {
     System.out.println(result.group(i));
 }
 s.close();

  1. 缓冲读取器:
  • 从字符输入流中读取文本,缓冲字符,以便有效地读取字符、数组和行。

  • 可以指定缓冲区大小,也可以使用默认大小。默认值对于大多数用途来说已经足够大了。

通常,对 Reader 发出的每个读取请求都会导致对基础字符或字节流发出相应的读取请求。因此,建议将 BufferedReader 包装在 read() 操作可能成本高昂的任何 Reader 周围,例如 FileReaders 和 InputStreamReaders。例如

BufferedReader in = new BufferedReader(new FileReader("foo.in"));
 

将缓冲指定文件中的输入。如果没有缓冲,每次调用 read() 或 readLine() 都可能导致从文件中读取字节,将其转换为字符,然后返回,这可能非常低效。 使用 DataInputStreams 进行文本输入的程序可以通过将每个 DataInputStream 替换为适当的 BufferedReader 来本地化。

使用的来源:https://docs.oracle.com

18赞 dhS 1/1/2017 #11

BufferedReaderScanner 之间的区别在于:

  1. BufferedReader 读取数据,但 Scanner 分析数据。
  2. 您只能使用 BufferedReader 读取 String,使用 Scanner 您可以读取不同的数据类型,例如 .int
  3. BufferedReader 比 Scanner 更旧,它是在 上添加的,而 Scanner 是在发布时添加的。JDK 1.1JDK 5
  4. Scanner 的 1KB 相比,BufferedReader 的缓冲区大小更大 (8KB)。
  5. BufferedReader 更适合读取长字符串的文件,而 Scanner 更适合从命令提示符读取小用户输入。
  6. BufferedReader 是同步的,而 Scanner 不是同步的,这意味着您不能在多个线程之间共享 Scanner
  7. BufferedReaderScanner 更快,因为它不会花时间进行解析。
  8. Scanner 相比,BufferedReader 的速度要快一些。
  9. BufferedReader 来自包,而 Scanner 来自包。java.iojava.util

根据这些点,我们可以选择我们的选择。

感谢您的阅读!

21赞 Raman Gupta 10/1/2017 #12

BufferedReaderScanner 之间的区别如下:

  1. BufferedReader 已同步,但 Scanner 未同步
  2. BufferedReader 是线程安全的,但 Scanner 不是线程安全的。
  3. BufferedReader 具有较大的缓冲区内存,但 Scanner 具有较小的缓冲区内存
  4. BufferedReader 速度更快,但 Scanner 执行速度较慢
  5. 用于从控制台读取行的代码:

缓冲读取器

InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String st = br.readLine();
       
// You can make the object InputStreamReader object inside the BufferReader method.
BufferReader br = new BufferedReader(InputStreamReader(System.in));
String st = br.readLine();

// You can even inspect the type of the input stream manually by using Parse method which accepts string parameter.
int x = Integer.parseInt(br.readLine());

// Or you can pass the object directly.
int x = Integer.parseInt(st);

扫描仪

Scanner sc = new Scanner(System.in);
String st = sc.nextLine();