datainputstream 必须与 dataoutputstream 配套使用,按固定字节长度和大端序严格顺序读取基础类型,不支持自动定位、类型推断或非java序列化数据解析。

DataInputStream 本身不负责“精准”读取,它只是按约定格式解析二进制流——前提是写入端用了配套的 DataOutputStream,并严格遵循 Java 的数据序列化规则。它不能从任意二进制文件中智能识别 int 或 double 的位置,必须依赖写入时的顺序和类型匹配。
必须搭配 DataOutputStream 使用
DataInputStream 的 readInt()、readDouble() 等方法,是按固定字节长度和大端序(Big-Endian)解析的:
- readInt() 总是读 4 个连续字节,拼成一个 int(高位在前)
- readDouble() 总是读 8 个连续字节,按 IEEE 754 双精度格式还原
- readUTF() 先读 2 字节长度,再读对应数量的 Modified UTF-8 字节
如果源数据不是由 DataOutputStream 写入的(比如用 FileOutputStream 直接 write(int)),那么 readInt() 会错误地把多个独立字节拼成一个整数,结果完全不可预测。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
读取过程必须严格按写入顺序进行
没有自动跳过、定位或类型推断能力。你调用 readInt(),它就从当前位置读 4 字节;紧接着调用 readDouble(),就继续读接下来的 8 字节。一旦顺序错位(比如多调一次 readByte()),后续所有读取都会偏移失效。
- 写入端示例:
dos.writeInt(100); dos.writeDouble(3.14); dos.writeBoolean(true); - 读取端必须严格对应:
int a = dis.readInt(); double b = dis.readDouble(); boolean c = dis.readBoolean(); - 中间不能插其他 read() 或跳过操作,否则字节对齐被破坏
注意 EOF 和异常边界
DataInputStream 不会在读到流末尾时“优雅返回默认值”,而是直接抛出 EOFException —— 这是正常行为,不是错误。
- readInt() 在剩余字节数不足 4 时抛
EOFException - readFully(byte[]) 在无法填满数组时也抛
EOFException - 建议用 try-catch 显式捕获 EOFException 来判断数据结束,而不是依赖返回值
别把它当通用二进制解析器
它不支持跳转、随机读、字段名查找或大小端切换。如果你需要解析非 Java 生产的二进制协议(如网络包、图像头、自定义结构体),应该用 ByteBuffer 配合 order()、getShort()、getInt() 等方法,或者用专门的二进制解析库(如 JBBP、Kaitai Struct)。
- DataInputStream 是 Java 原生序列化生态的一环,核心用途是配合 DataOutputStream 做简单跨进程/跨文件的基础类型交换
- 处理图片、音频、Protobuf、JSON 二进制等,都不该用它
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










