316

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

我的问题是:

  • 是否Scanner表现得一样好BufferedReader
  • 为什么你会选择ScannerBufferedReader反之亦然?
4

12 回答 12

221

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

实际上,您可以将 a 传递BufferedReader给 ascanner作为要解析的字符源。

于 2010-02-09T18:20:04.087 回答
214

在当前最新的 JDK6 版本/构建 (b27) 中,与( 8192 字符Scanner) 相比,缓冲区 ( 1024 字符)更小,但绰绰有余。BufferedReader

至于选择,Scanner如果要解析文件,请使用,BufferedReader如果要逐行读取文件,请使用。另请参阅他们之前链接的 API 文档的介绍性文本。

  • 解析= 将给定的输入解释为标记(部分)。它能够直接将特定部分作为 int、string、decimal 等返回给您。另请参阅类nextXxx()中的所有这些方法Scanner
  • 阅读=愚蠢的流媒体。它不断地回馈你所有的角色,如果你想匹配或组成一些有用的东西,你必须手动检查这些角色。但是,如果您无论如何都不需要这样做,那么阅读就足够了。
于 2010-02-09T18:21:12.543 回答
78

请参阅此链接,从那里引用以下内容:

BufferedReader 是一个简单的类,旨在有效地从底层流中读取。通常,由 Reader(如 FileReader)发出的每个读取请求都会导致对底层流发出相应的读取请求。每次调用 read() 或 readLine() 都可能导致从文件中读取字节,转换为字符,然后返回,这可能非常低效。如果 Reader 在 BufferedReader 中变形,效率会显着提高。

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

另一方面,扫描仪内置了更多的奶酪。它可以做 BufferedReader 可以做的所有事情,而且效率也相同。但是,除此之外,Scanner 可以使用正则表达式解析基本流的基本类型和字符串。它还可以使用您选择的分隔符标记基础流。它还可以不考虑分隔符对底层流进行前向扫描!

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

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

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

于 2011-12-11T15:50:12.870 回答
42
  1. BufferedReader具有比 Scanner 大得多的缓冲内存。BufferedReader如果您想从流中获取长字符串,请使用,如果Scanner您想从流中解析特定类型的令牌,请使用。

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

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

  4. ScannerBufferedReader立即抛出IOException 时隐藏它。

于 2014-02-11T09:39:21.110 回答
19

我建议BufferedReader用于阅读文本。Scanner隐藏IOExceptionBufferedReader立即扔掉它。

于 2011-04-15T10:07:54.623 回答
18

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();
于 2017-10-01T08:52:02.943 回答
10

BufferedReaderScanner的区别在于:

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

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

谢谢阅读!

于 2016-12-31T17:33:51.500 回答
8

主要区别:

  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

于 2016-11-30T16:34:22.383 回答
3

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

1) BufferedReader 2) Scanner 3) 命令行参数

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

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

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

更多信息请参考:

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

于 2015-06-16T14:42:22.373 回答
2

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

从控制台读取输入时,有两个选项可以实现。第一次使用Scanner,另一个使用BufferedReader。两者都有不同的特点。这意味着差异如何使用它。

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

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

  • 扫描器将给定的输入视为令牌。BufferedReader作为流线/字符串。
  • 扫描仪使用正则表达式对给定的输入进行标记。使用BufferedReader必须编写额外的代码。
  • BufferedReaderScanner *point no. 快。2
  • Scanner不同步,BufferedReader同步

Scanner从那时起JDK 1.5和更高。

什么时候应该使用 Scanner 或 Buffered Reader?

查看它们之间的主要区别,一个使用标记化,另一个使用流线。当您需要解析功能时,请Scanner改用。但是,我更舒服BufferedReader。当您需要从文件中读取数据时,请使用BufferedReader,因为它在读取文件时使用缓冲内存,从而减少了物理驱动器的使用。或者,您可以将BufferedReader其用作Scanner.

于 2014-03-01T09:34:26.650 回答
0
  1. BufferedReader 可能会给您带来更好的性能(因为 Scanner 基于 InputStreamReader,请查看源代码)。哎呀,从它使用的文件中读取数据nio。当我针对大文件的性能测试nio性能时,性能会更好一些。BufferedReadernio
  2. 要从文件中读取数据,请尝试Apache Commons IO
于 2010-02-09T18:22:09.500 回答
0

我更喜欢Scanner它,因为它不会抛出已检查的异常,因此它的使用会产生更精简的代码。

于 2016-11-28T12:40:03.703 回答