1. Overview
1.概述
Java offers a variety of tools and functions to engage with user input. System.in.read() is one of the frequently used methods for reading input from the console. In this article, we’ll explore its functionality and how it can be used in Java.
Java 提供了各种工具和函数来处理用户输入。 System.in.read() 是从控制台读取输入的常用方法之一。在本文中,我们将探讨它的功能以及如何在 Java 中使用它。
2. What Is System.in.read()?
2.什么是 System.in.read()?
The Java method System.in.read() reads a byte from the standard input stream, usually linked to the keyboard or another source. It’s part of the System class and provides a low-level mechanism for reading byte-oriented input:
Java 方法System.in.read()从标准输入流中读取一个字节,通常链接到键盘或其他源。它是 System 类的一部分,为读取面向字节的输入提供了底层机制:
public static int read() throws IOException
Here, the method returns an integer representing the ASCII value of the character read. We need to cast the ASCII integer value to a character to see the actual value. If the end of the stream has been reached, it returns -1.
该方法返回一个整数,代表读取字符的 ASCII 值。我们需要将 ASCII 整数值转换为字符,以查看实际值。如果数据流已经结束,则返回 -1。
It’s important to note that System.in.read() reads only a single byte at a time. If we need to read a whole line or handle different data types, we may need to use other methods or classes such as BufferedReader or Scanner.
需要注意的是,System.in.read()一次只能读取一个字节。如果我们需要读取整行或处理不同的数据类型,可能需要使用其他方法或类,如 BufferedReader 或 Scanner. 。
3. Other Input Sources
3.其他输入源
While System.in is commonly used for console input, System.in.read() can also be redirected to read from various other sources, including files, network connections, and user interfaces.
虽然 System.in 通常用于控制台输入,但 System.in.read() 也可以被重定向以读取其他各种来源的内容,包括文件、网络连接和用户界面。
These alternative input sources enable a wide range of applications, such as reading configuration files, managing client-server communication, interacting with databases, handling user interfaces, and interfacing with external devices like sensors and IoT devices.
这些替代输入源可支持多种应用,如读取配置文件、管理客户端与服务器通信、与数据库交互、处理用户界面以及与传感器和物联网设备等外部设备连接。
4. Reading a Single Character
4.读取单个字符
The most straightforward use of System.in.read() is to read a single character:
System.in.read() 最直接的用途是读取单个字符:
void readSingleCharacter() {
System.out.println("Enter a character:");
try {
int input = System.in.read();
System.out.println((char) input);
}
catch (IOException e) {
System.err.println("Error reading input: " + e.getMessage());
}
}
Since System.in.read() throws an IOException, a checked exception, we need to handle it. In the above example, we capture the IOException and output an error message to the standard error stream.
由于System.in.read()会抛出一个IOException(一个已检查异常),因此我们需要对其进行处理。在上述示例中,我们捕获了 IOException 并将错误消息输出到标准错误流中。
Let’s perform a test to confirm that everything works as expected by reading a character from the input stream:
让我们进行一次测试,从输入流中读取一个字符,以确认一切正常:
@Test
void givenUserInput_whenUsingReadSingleCharacter_thenRead() {
System.setIn(new ByteArrayInputStream("A".getBytes()));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
SystemInRead.readSingleCharacter();
assertEquals("Enter a character:\nA", outputStream.toString().trim());
}
Here, we redirect System.in.read() to read from a ByteArrayInputStream. By doing so, we avoid prompting the user for input while running the test, and we can assert the console output.
在这里,我们重定向 System.in.read() 从 ByteArrayInputStream 中读取数据。通过这种方式,我们可以避免在运行测试时提示用户输入,并且可以断言控制台输出。
5. Reading Multiple Characters
5.读取多个字符
While System.in.read() reads one byte at a time, we might often need to read multiple characters. One common approach is to read continuously within a loop until a specific condition is met:
虽然 System.in.read() 一次只读取一个字节,但我们可能经常需要读取多个字符。一种常见的方法是在一个循环中连续读取,直到满足特定条件:
void readMultipleCharacters() {
System.out.println("Enter characters (Press 'Enter' to quit):");
try {
int input;
while ((input = System.in.read()) != '\n') {
System.out.print((char) input);
}
} catch (IOException e) {
System.err.println("Error reading input: " + e.getMessage());
}
}
Here, we use System.in.read() inside a while loop that continues execution until we press the enter key. Let’s test the new behavior with a unit test:
在这里,我们在一个 while 循环中使用 System.in.read() 继续执行,直到我们按下回车键。让我们通过单元测试来测试新行为:
@Test
void givenUserInput_whenUsingReadMultipleCharacters_thenRead() {
System.setIn(new ByteArrayInputStream("Hello\n".getBytes()));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
SystemInRead.readMultipleCharacters();
assertEquals("Enter characters (Press 'Enter' to quit):\n" + "Hello", outputStream.toString().trim());
}
6. System.in.read() With Parameters
6.System.in.read() 带参数
There are two other versions available for the System.in.read() method, which returns the number of bytes read from the input stream.
System.in.read()方法有两个其他版本,可返回从输入流读取的字节数。
6.1. Read With Multiple Parameters
6.1.读取多个参数
This method reads from the input stream and stores the data in a byte array, starting at the specified offset and continuing up to the specified length. The method may read fewer bytes than the specified length if it encounters the end of the stream:
本方法从输入流中读取数据,并将数据存储到 字节数组中,从指定的偏移量开始,直到指定的长度。如果遇到数据流的末尾,该方法读取的字节数可能少于指定长度:
void readWithParameters() {
try {
byte[] byteArray = new byte[5];
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = System.in.read(byteArray, 0, byteArray.length)) != -1) {
System.out.print("Data read: " + new String(byteArray, 0, bytesRead));
totalBytesRead += bytesRead;
}
System.out.println("\nBytes read: " + totalBytesRead);
} catch (IOException e) {
e.printStackTrace();
}
}
In the above example, we read bytes from the standard input stream into a byte array and print the number of bytes read and the data. We can perform a test to verify its expected behavior:
在上面的示例中,我们将字节从标准输入流读取到字节数组中,并打印读取的字节数和数据。我们可以执行测试来验证其预期行为:
@Test
void givenUserInput_whenUsingReadWithParameters_thenRead() {
System.setIn(new ByteArrayInputStream("ABC".getBytes()));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
SystemInRead.readWithParameters();
assertEquals("Data read: ABC\n" + "Bytes Read: 3", outputStream.toString().trim());
}
6.2. Read With Single Parameter
6.2.使用单一参数读取
This method is another version of the System.in.read() method, which accepts an array of byte as a parameter. It internally calls System.in.read(byte[] b, int off, int len).
该方法是 System.in.read() 方法的另一个版本,它接受一个 byte 数组作为参数。它在内部调用 System.in.read(byte[] b, int off, int len).
The method is defined with the following signature:
该方法的签名如下
public static int read(byte[] b) throws IOException
7. Limitations
7.局限性
While System.in.read() is straightforward, it has some limitations:
虽然System.in.read()简单明了,但也有一些局限性:
- It reads only a single byte at a time, making it less efficient for reading completed lines or handling multi-byte characters.
- The method blocks until it receives input. It might cause the application to appear unresponsive if the user does not provide input.
- For more complex input processing, such as handling integers or strings, it’s better to use other classes like BufferedReader or Scanner.
8. Conclusion
8.结论
In this article, we looked at the System.in.read() method in Java and explored how it can be used in our application. It provides a fundamental yet powerful way to handle user input directly from the standard input stream.
在本文中,我们介绍了 Java 中的 System.in.read() 方法,并探讨了如何在应用程序中使用该方法。它为直接处理来自标准输入流的用户输入提供了一种基本而强大的方法。
By understanding its usage, handling errors, and incorporating it into more complex input scenarios, we can create interactive and user-friendly applications.
通过了解其用法、处理错误并将其纳入更复杂的输入场景,我们可以创建交互式和用户友好的应用程序。
As always, the full source code is available over on GitHub.
一如既往,您可以在 GitHub 上获取完整的源代码。