DataInputStream 读取二进制数值必须严格匹配 DataOutputStream 写入的类型、顺序、字节格式(大端)及 readUTF 的 modified UTF-8 规则,否则导致错位、异常或解析错误。

使用 DataInputStream 读取二进制数值的关键,在于它严格按 Java 基本类型的字节长度和大端(Big-Endian)格式解析,且要求数据源的字节序列必须与写入时用 DataOutputStream 生成的格式完全一致。
确保写入端用 DataOutputStream 写入
DataInputStream 不是通用二进制解析器,它只认自己“亲兄弟”DataOutputStream 写出的格式。比如:
-
writeInt(0x12345678)固定写入 4 字节:0x12 0x34 0x56 0x78(大端) -
writeShort((short)0xABCD)写入 2 字节:0xAB 0xCD -
writeBoolean(true)写入 1 字节:0x01
如果原始数据来自 C/C++、网络协议或文件不是用 DataOutputStream 生成的,直接用 DataInputStream 读会错位或抛 EOFException。
按写入顺序和类型逐个调用对应 read 方法
必须严格匹配写入时的类型、顺序和数量。例如写入顺序是:writeInt → writeDouble → writeUTF,那么读取时必须依次调用:
立即学习“Java免费学习笔记(深入)”;
-
readInt()(返回int,自动处理 4 字节+大端) -
readDouble()(读 8 字节,按 IEEE 754 双精度解析) -
readUTF()(读长度前缀 + UTF-8 编码内容,非普通字符串)
跳过、多读、少读或类型错配(如用 readShort() 读一个 int 的前两字节),都会导致后续全部错乱。
注意 readUTF 和字符串编码的特殊性
readUTF() 不是读普通 UTF-8 字符串。它先读 2 字节无符号长度(length),再读 length 字节的**修改版 UTF-8**(modified UTF-8):\u0000 编码为 0xC0 0x80,不支持 \uDC00–\uDFFF 范围的代理对。若需读标准 UTF-8 字符串,应改用:
-
readFully(byte[] b)+new String(b, StandardCharsets.UTF_8) - 或用
BufferedInputStream配合InputStreamReader
检查流状态,避免 EOF 或截断
DataInputStream 的 readXxx() 方法在数据不足时会抛 EOFException(如只剩 3 字节却调 readInt())。生产环境建议:
- 读取前用
available()仅作参考(不可靠,尤其网络流) - 更稳妥的是捕获
EOFException或IOException,结合业务逻辑判断是否属于正常结束 - 对关键字段,可先
readUnsignedByte()判断标记字节,再决定是否继续读后续结构


















