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

我的问题是:

扫描器的性能和BufferedReader一样好吗? 为什么你会选择扫描器而不是BufferedReader,反之亦然?


当前回答

主要区别:

扫描仪


简单的文本扫描器,可以解析基本类型和字符串使用正则表达式。 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();

BufferedReader:

从字符输入流中读取文本,缓冲字符,以便有效地读取字符、数组和行。 可以指定缓冲区大小,也可以使用默认大小。默认值对于大多数目的来说足够大。

一般来说,对Reader发出的每个读请求都会导致对底层字符或字节流发出相应的读请求。因此,建议将BufferedReader包装在read()操作代价较高的Reader周围,例如filereader和inputstreamreader。例如,

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

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

来源:https://docs.oracle.com

其他回答

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

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

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

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

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

如需更多信息,请参考:

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

BufferedReader has significantly larger buffer memory than Scanner. Use BufferedReader if you want to get long strings from a stream, and use Scanner if you want to parse specific type of token from a stream. Scanner can use tokenize using custom delimiter and parse the stream into primitive types of data, while BufferedReader can only read and store String. BufferedReader is synchronous while Scanner is not. Use BufferedReader if you're working with multiple threads. Scanner hides IOException while BufferedReader throws it immediately.

请看这个链接,下面是引用自那里的:

A BufferedReader is a simple class meant to efficiently read from the underling stream. Generally, each read request made of a Reader like a FileReader causes a corresponding read request to be made to underlying stream. Each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient. Efficiency is improved appreciably if a Reader is warped in a BufferedReader. BufferedReader is synchronized, so read operations on a BufferedReader can safely be done from multiple threads. A scanner on the other hand has a lot more cheese built into it; it can do all that a BufferedReader can do and at the same level of efficiency as well. However, in addition a Scanner can parse the underlying stream for primitive types and strings using regular expressions. It can also tokenize the underlying stream with the delimiter of your choice. It can also do forward scanning of the underlying stream disregarding the delimiter! A scanner however is not thread safe, it has to be externally synchronized. The choice of using a BufferedReader or a Scanner depends on the code you are writing, if you are writing a simple log reader Buffered reader is adequate. However if you are writing an XML parser Scanner is the more natural choice. Even while reading the input, if want to accept user input line by line and say just add it to a file, a BufferedReader is good enough. On the other hand if you want to accept user input as a command with multiple options, and then intend to perform different operations based on the command and options specified, a Scanner will suit better.

我建议使用BufferedReader来读取文本。扫描器隐藏IOException而BufferedReader立即抛出它。

主要区别:

扫描仪


简单的文本扫描器,可以解析基本类型和字符串使用正则表达式。 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();

BufferedReader:

从字符输入流中读取文本,缓冲字符,以便有效地读取字符、数组和行。 可以指定缓冲区大小,也可以使用默认大小。默认值对于大多数目的来说足够大。

一般来说,对Reader发出的每个读请求都会导致对底层字符或字节流发出相应的读请求。因此,建议将BufferedReader包装在read()操作代价较高的Reader周围,例如filereader和inputstreamreader。例如,

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

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

来源:https://docs.oracle.com