Java中的BufferedReader、Console和Scanner
1. 概述
在本文中,我们将介绍Java 中BufferedReader、Console和Scanner类之间的区别。 要深入了解每个主题,我们建议您查看我们关于 Java Scanner 、Console I/O in Java 和BufferedReader 的单独文章。
2. 用户输入
鉴于传递给构造函数的底层流,BufferedReader和Scanner类都能够处理更广泛的用户输入**,例如字符串、文件、系统控制台(通常连接到键盘)和套接字。
另一方面,Console类旨在仅访问与当前 Java 虚拟机关联的基于字符的系统控制台(如果有的话)。
让我们看一下接受不同输入的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()));
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());
Console类只能通过方法调用使用:
Console console = System.console();
请记住,当我们使用 Console类时,如果我们在 Eclipse 或 IntelliJ IDEA 等 IDE 中运行代码,则 JVM 关联的系统控制台不可用。
3. 用户输出
**与不向输出流写入任何内容的 BufferedReader和Scanner类相比,Console类提供了一些方便的方法,**例如readPassword (String fmt, Object…args)、*readLine(String fmt, Object…args)*和 printf ( String format,Object… args), 将提示写入系统控制台的输出流:
String firstName = console.readLine("Enter your first name please: ");
console.printf("Welcome " + firstName );
因此,当我们编写与系统控制台交互的程序时,Console类将通过删除不必要的System.out.println来简化代码 。
4.解析输入
Scanner类可以使用正则表达式解析原始类型和字符串。
它使用自定义分隔符模式将其输入分解为标记,默认情况下匹配空格:
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和Console类只是按原样读取输入流。
5. 读取安全数据
Console类有方法 *readPassword()*和 *readPassword(String fmt, Object… args)*来读取禁用回显的安全数据,这样用户就不会看到他们正在输入的内容:
String password = String.valueOf(console.readPassword("Password :"));
BufferedReader和Scanner 没有能力这样做。**
6. 线程安全
BufferedReader中的 read 方法和Console 中的 read 和 write 方法 都是同步的,而Scanner类中的则不是。如果我们在多线程程序中读取用户输入, BufferedReader或 Console 将是更好的选择。
7. 缓冲区大小
BufferedReader中的缓冲区大小为 8 KB,而Scanner类中的缓冲区大小为 1 KB 。**
此外,如果需要,我们可以在BufferedReader类的构造函数中指定缓冲区大小。这将有助于从用户输入中读取长字符串。 Console类在从系统控制台读取时没有缓冲区,但它有一个缓冲的输出流来写入系统控制台。
8. 杂项
在选择适用于各种情况的类时,有些差异不是我们考虑的主要因素。
8.1. 关闭输入流
一旦我们创建了BufferedReader或 Scanner的实例,我们需要记住关闭它以避免内存泄漏。但这不会发生在Console类中——我们不需要在使用后关闭系统控制台。
8.2. 异常处理
虽然Scanner 和Console 采用未经检查的异常方法,但 BufferedReader 中的方法 抛出检查异常,这迫使我们编写样板 try-catch 语法来处理异常。