1. Overview
1.概述
In this article, we’re going to walk through the differences between BufferedReader, Console, and Scanner classes in Java.
在本文中,我们将了解Java中BufferedReader、Console和Scanner类之间的区别。
To have a deep dive on each topic, we suggest having a look at our individual articles on Java Scanner, Console I/O in Java, and BufferedReader.
要深入了解每个主题,我们建议查看我们关于Java Scanner、Java中的控制台I/O和BufferedReader的单独文章。
2. User Input
2.用户输入
Given the underlying stream passed to the constructors, both BufferedReader and Scanner classes are able to handle a wider range of user input, such as a string, file, system console (which is typically connected to the keyboard), and socket.
鉴于传递给构造函数的底层流,BufferedReader和Scanner类都能够处理更广泛的用户输入,例如字符串、文件、系统控制台(通常与键盘相连)和套接字。
On the other hand, the Console class is designed to only access the character-based system console, if any, associated with the current Java virtual machine.
另一方面,Console类被设计为只访问基于字符的系统控制台,如果有的话,与当前的Java虚拟机相关。
Let’s have a look at the BufferedReader constructors, which accept different inputs:
让我们来看看接受不同输入的BufferedReader构造函数。
BufferedReader br = new BufferedReader(
new StringReader("Bufferedreader vs Console vs Scanner in Java"));
BufferedReader br = new BufferedReader(
new FileReader("file.txt"));
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in))
Socket socket = new Socket(hostName, portNumber);
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
The Scanner class could similarly accept different inputs in its constructors as well:
Scanner类也可以类似地在其构造函数中接受不同的输入。
Scanner sc = new Scanner("Bufferedreader vs Console vs Scanner in Java")
Scanner sc = new Scanner(new File("file.txt"));
Scanner sc = new Scanner(System.in);
Socket socket = new Socket(hostName, portNumber);
Scanner sc = new Scanner(socket.getInputStream());
The Console class is available only via the method call:
Console类只能通过方法调用获得。
Console console = System.console();
Please bear in mind that when we use the Console class, the JVM associated system console isn’t available if we run the code within an IDE such as Eclipse or IntelliJ IDEA.
请记住,当我们使用Console类时,如果我们在Eclipse或IntelliJ IDEA等IDE中运行代码,JVM相关的系统控制台就不可用。
3. User Output
3.用户输出
In contrast to BufferedReader and Scanner classes, which don’t write anything to the output stream, the Console class offers some convenient methods like readPassword (String fmt, Object… args), readLine (String fmt, Object… args), and printf (String format,Object… args), to write the prompt to the system console’s output stream:
与BufferedReader和Scanner类相比,它们不向输出流写任何东西,Console类提供了一些方便的方法,如readPassword (String fmt, Object… args), readLine (String fmt, Object… args), 和printf (String format,Object… args)。args),readLine(String fmt, Object… args),和printf(String format,Object… args),将提示写入系统控制台的输出流。
String firstName = console.readLine("Enter your first name please: ");
console.printf("Welcome " + firstName );
So when we write a program to interact with the system console, Console class will simplify the code by removing unnecessary System.out.println.
因此,当我们写一个与系统控制台互动的程序时,Console类将通过删除不必要的System.out.println来简化代码。
4. Parsing Input
4.输入解析
The Scanner class can parse primitive types and strings using regular expressions.
Scanner类可以使用正则表达式解析原始类型和字符串。
It breaks its input into tokens using a custom delimiter pattern, which by default matches whitespace:
它使用一个自定义的分隔符模式将其输入分解成标记,默认情况下,该模式匹配空白。
String input = "Bufferedreader vs Console vs Scanner";
Scanner sc = new Scanner(input).useDelimiter("\\s*vs\\s*");
System.out.println(sc.next());
System.out.println(sc.next());
System.out.println(sc.next());
sc.close();
BufferredReader and Console classes simply read the input stream as it is.
BufferredReader和Console类只是按原样读取输入流。
5. Reading Secure Data
5.读取安全数据
The Console class has methods readPassword() and readPassword (String fmt, Object… args) to read the secure data with echoing disabled so users will not see what they are typing:
Console类有readPassword()和readPassword (String fmt, Object… args) 来读取安全数据,并禁用回声,这样用户就不会看到他们正在输入什么。
String password = String.valueOf(console.readPassword("Password :"));
BufferedReader and Scanner have no capability to do so.
BufferedReader和Scanner没有这样做的能力。
6. Thread Safe
6.螺纹安全
The read methods in BufferedReader and the read and write methods in Console are all synchronized, whereas those in the Scanner class are not. If we read the user input in a multi-threaded program, either BufferedReader or Console will be a better option.
BufferedReader中的读取方法和Console中的读写方法都是synchronized,而Scanner类中的方法则不是。如果我们在一个多线程的程序中读取用户的输入,BufferedReader或Console将是一个更好的选择。
7. Buffer Size
7.缓冲区大小
The buffer size is 8 KB in BufferedReader as compared to 1 KB in Scanner class.
在BufferedReader中,缓冲区大小为8KB,而在Scanner类中为1KB。
In addition, we can specify the buffer size in the constructor of the BufferedReader class if needed. This will help when reading the long strings from user input. Console class has no buffer when reading from the system console, but it has a buffered output stream to write to the system console.
此外,如果需要的话,我们可以在BufferedReader类的构造函数中指定缓冲区大小。这将有助于从用户输入中读取长字符串。Console类在从系统控制台读取时没有缓冲区,但它有一个缓冲的输出流来写给系统控制台。
8. Miscellaneous
8.杂项
There are some differences that are not the major factors we consider when choosing the appropriate class to use in various situations.
有一些差异并不是我们在各种情况下选择适当类别时考虑的主要因素。
8.1. Closing the Input Stream
8.1.关闭输入流
Once we create the instance of BufferedReader or Scanner, we need to remember to close it in order to avoid a memory leak. But this doesn’t happen with the Console class — we don’t need to close the system console after use.
一旦我们创建了BufferedReader或Scanner的实例,我们需要记得关闭它,以避免内存泄漏。但这种情况不会发生在Console类中–我们不需要在使用后关闭系统控制台。
8.2. Exception Handling
8.2.异常处理
While Scanner and Console go with the unchecked exception approach, methods in BufferedReader throw checked exceptions, which forces us to write boilerplate try-catch syntax to handle the exceptions.
当Scanner和Console采用未检查的异常方法时,BufferedReader中的方法会抛出检查的异常,这迫使我们编写模板式的try-catch语法来处理这些异常。
9. Conclusion
9.结语
Now that we’ve stated the differences among these classes, let’s come up with some rules of thumb regarding which one(s) are best suited to tackle different situations:
现在我们已经说明了这些类别之间的差异,让我们提出一些经验法则,说明哪一个(几个)最适合处理不同的情况。
- Use BufferedReader if we need to read long strings from a file, as it has better performance than Scanner
- Consider Console if we’re reading secure data from the system console and want to hide what is being typed
- Use Scanner if we need to parse the input stream with a custom regular expression
- Scanner would be preferred when we interact with the system console, as it offers fine-grained methods to read and parse the input stream. In addition, the performance drawback is not a big problem, as in most cases, the nextXXX methods are blocking and wait for manual input
- In a thread-safe context, consider BufferedReader unless we have to use features specific to the Console class