在 Java 中,BufferReader 类和 Scanner 类都可用于读取输入,但由于其底层实现不同因此它们的性能也不同。 一般来说,BufferReader 类的处理速度比 Scanner 类更快,这是因为它处理输入和解析的方式不同。 本文将对详细说明是什么原因让BufferReader处理IO的效率优与Scanner。
主要概念
BufferReader
BufferReader 是 java.io 包中的一个类,用于从字符输入流中读取文本,缓冲字符以提供高效的字符、数组和行的读取,在读取过程中 BufferReader 类并不会解析输入数据,因此在进行简单的读取操作时速度更快。
要点:
可以读取原始的字符或字符串。
不提供解析功能。
适合高效地读取大块数据(大文件数据)。
示例:
/*package whatever //do not write package name here */ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class BufferedReaderExample { public static void main(String[] args) { try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
java.io.FileNotFoundException: input.txt (没有这样的文件或目录)
在 java.base/java.io.FileInputStream.open0(Native 方法)
在 java.base/java.io.FileInputStream.open(FileInputStream.java:219)
在 java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
在 java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
在 java.base/java.io.FileReader.<init>(FileReader.java:60)
在 BufferedReaderExample.main(BufferedReaderExample.java:10)
在这个示例中,BufferReader 可以高效地读取文件中的每一行,而不会产生任何解析开销。
Scanner
Scanner 是 java.util 软件包中的一个类,它使用分隔符模式(默认情况下与空格匹配)将输入内容分解成标记。 Scanner 类可以使用正则表达式解析原始类型和字符串。
要点:
它可以同时读取和解析输入。
它可以提供用于解析不同数据类型的内置方法。例如 nextInt()、nextDouble()。
它便于在单个步骤中读取和解析输入,但由于解析的开销而较慢。
例
/*package whatever //do not write package name here */ import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ScannerExample { public static void main(String[] args) { try (Scanner scanner = new Scanner(new File("input.txt"))) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } } }
java.io.FileNotFoundException: input.txt (没有这样的文件或目录)
在 java.base/java.io.FileInputStream.open0(Native 方法)
在 java.base/java.io.FileInputStream.open(FileInputStream.java:219)
在 java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
在 java.base/java.util.Scanner.<init>(Scanner.java:639)
在 ScannerExample.main(ScannerExample.java:10)
在此示例中,Scanner 可以从文件中读取每一行,也可以分析标记,但与 BufferReader 相比,这会带来额外的开销。
性能比较
之所以出现性能差异,是因为 BufferReader 只读取字符而不会尝试解析,但是 Scanner 会根据指定的分隔符和数据类型对输入进行解析。 这一解析步骤可能需要额外的处理时间,使得 Scanner 在处理大文件时比 BufferReader 要慢。
结论
虽然 BufferReader 和 Scanner 都适用于在 Java 中读取输入内容,但 BufferReader 由于不需要解析开销,因此在简单的读取操作中效率更高。而 Scanner 提供了同时读取和解析输入的更便捷方法,如果输入文件不大或者有解析输入内容的需求时使用Scanner更合适,
所以对于性能非常重要且不需要解析的场景最好使用 BufferReader,如果更看重易用性和解析能力,Scanner 则是更好的选择。