Java中System.in与System.out流通信:readUTF()和writeUTF()问题
问题分析与解决方案
1. 为什么readUTF()无法结束输入?
DataInputStream.readUTF()是专门处理二进制格式UTF字符串的方法,它的执行逻辑是:
- 先读取2个字节的无符号整数,作为后续字符串的字节长度
- 再读取对应长度的字节,解码为UTF-8字符串
你在控制台输入的是普通文本,没有提前写入这个长度前缀,导致readUTF()会一直等待足够的字节数,自然不会响应回车、换行这类文本输入的结束符。
2. 为什么writeUTF()控制台无输出?
DataOutputStream.writeUTF()会把字符串编码成带长度前缀的二进制格式:
- 先写入2个字节的长度值
- 再写入字符串的UTF-8字节
控制台是文本终端,无法解析这个二进制前缀(前缀是不可见的控制字节),所以你看不到预期的"Hello"——并不是没有输出,而是输出内容不符合文本终端的解析规则。
正确的控制台文本交互方式
DataInputStream/DataOutputStream的设计目标是二进制数据流场景(比如文件存储、网络通信),不适合控制台的文本交互。如果要实现控制台的字符串读写,应该使用面向文本的流:
示例代码
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; public class ConsoleIO { public static void main(String[] args) { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter pw = new PrintWriter(System.out, true); // 自动flush try { // 读取控制台输入 pw.println("请输入字符串:"); String input = br.readLine(); pw.println("你输入的是:" + input); // 输出字符串到控制台 pw.println("直接输出的字符串:Hello"); } catch (IOException e) { e.printStackTrace(); } finally { try { br.close(); pw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
如果非要使用Data系列流(二进制场景)
如果是在二进制场景下(比如读写二进制文件),readUTF()和writeUTF()需要配对使用,示例如下:
写入二进制文件
import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class WriteBinary { public static void main(String[] args) { try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) { dos.writeUTF("Hello"); } catch (IOException e) { e.printStackTrace(); } } }
读取二进制文件
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class ReadBinary { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"))) { String str = dis.readUTF(); System.out.println(str); // 输出Hello } catch (IOException e) { e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者lautreboutdumonde
相关产品推荐
相关产品推荐

