dataoutputstream 的 writeint()、writedouble() 等方法严格按大端序和 ieee 754/补码标准编码,保证平台无关;writeutf() 与 readutf() 必须配对使用;必须包装 fileoutputstream,且需 close 或 try-with-resources 确保落盘。

writeInt() 和 writeDouble() 这类方法天然保证平台无关
DataOutputStream 的 writeInt()、writeDouble()、writeUTF() 等方法内部已固化字节序(大端序)和编码规则,无需手动处理字节序或类型对齐。只要用它写,就是平台无关的——不是“尽量做到”,而是 Java 规范强制要求。
关键点在于:它不依赖本地 CPU 字节序,也不受 JVM 实现影响;writeInt(0x12345678) 在 x86 和 ARM 机器上都写成 0x12 0x34 0x56 0x78 四个字节。
- 所有数值类型均按 IEEE 754(float/double)或二进制补码(int/long)标准编码
-
writeChar(int)写的是 UTF-16 码点高字节在前,不是字符编码意义上的“UTF-8” -
writeUTF(String)是 DataInputStream 专用格式:先写 2 字节长度(大端),再写 UTF-8 字节——不能用普通文本工具看,也不能用readLine()读
必须包装 FileOutputStream,不能直接 new DataOutputStream("file.dat")
DataOutputStream 是装饰器流,没有文件操作能力。试图传入字符串路径会编译失败——它只接受 OutputStream 子类实例。
常见错误写法:new DataOutputStream("data.bin") → 编译报错:no suitable constructor。
- 正确路径:先建
FileOutputStream,再套一层DataOutputStream - 如果目标目录不存在(如
"out/data.bin"),FileOutputStream会抛FileNotFoundException,需提前确保父目录存在 - 使用
FileOutputStream(File, boolean)构造函数可控制是否追加,但DataOutputStream本身无追加逻辑
writeUTF() 和 readUTF() 必须严格配对,混用 writeBytes() 就乱码
writeUTF("你好") 写出的是:2 字节长度(0x00 0x06)+ 6 字节 UTF-8 编码(E4 BD A0 E5 A5 BD);而 writeBytes("你好") 直接按平台默认编码(如 GBK)写入字节,长度不可预知,DataInputStream.readUTF() 会误读前两个字节为长度,导致后续全错。
- 写字符串必须用
writeUTF(),读必须用readUTF() - 不要用
writeChars()(写 UTF-16BE,每个字符占 2 字节,含 \0) - 如果要存纯 ASCII 字符串且长度固定,可用
write(byte[])+String.getBytes(StandardCharsets.US_ASCII),但失去自动长度标记
资源不 close 或不 try-with-resources 会导致数据没真正落盘
DataOutputStream 有内部缓冲区,默认大小 8192 字节。writeInt() 等调用只是把数据塞进缓冲区,不调 close() 或 flush(),操作系统可能根本没收到写请求——尤其小数据(如只写一个 int)时极易丢失。
- 推荐始终用 try-with-resources:
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("x.dat"))) { ... } - 手动管理时,
close()会隐式调用flush();单独flush()不释放底层文件句柄 - 若中途异常,未 close 的流可能让文件句柄泄漏,Linux 下容易触发 “Too many open files”
DataInputStream 的读取逻辑一字不差,哪怕多一个 writeBoolean() 或少一个 readInt(),后面所有字段都会偏移错位——这种错误不会报异常,只会读出完全不可理解的值。











