package com.xie.javase.hashmap;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ByteArrayOutputStreamTest02 {
public static void main(String[] args) throws IOException {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeUTF("fdjlfj");
oos.writeInt(123);
oos.writeBoolean(true);
oos.writeDouble(3.14);
//使用了包装流就需要手动刷新一下
oos.flush();
byte[] array = baos.toByteArray();
for(byte arrays:array){
System.out.println(arrays);
}
}
}
package com.xie.javase.hashmap;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ByteArrayOutputStreamTest02 {
public static void main(String[] args) throws IOException {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeUTF("fdjlfj");
oos.writeInt(123);
oos.writeBoolean(true);
oos.writeDouble(3.14);
byte[] array = baos.toByteArray();
for(byte arrays:array){
System.out.println(arrays);
}
//使用了包装流就需要手动刷新一下
oos.flush();
}
}
为啥这个oos.flush();放的位置不一样结果不一样?
关于 flush()
位置影响的解释
在你的两段代码中,flush()
方法的位置不同导致输出结果不同,这是因为 ObjectOutputStream
的缓冲机制和 ByteArrayOutputStream
的特性共同作用的结果。下面详细解释原因:
1. 关键机制分析
(1)ObjectOutputStream
的缓冲机制
ObjectOutputStream
内部维护一个缓冲区,写入操作(如writeUTF()
)会先存入缓冲区flush()
的作用:强制将缓冲区中的数据刷新到底层流(这里是ByteArrayOutputStream
)
(2)ByteArrayOutputStream
的特性
- 数据写入后会立即存储在内存的字节数组中
- 但需要通过
toByteArray()
或toString()
方法获取当前所有数据
2. 两种情况的对比
情况1:先 flush()
再 toByteArray()
oos.writeUTF("fdjlfj");
oos.writeInt(123);
oos.flush(); // 强制刷新缓冲区
byte[] array = baos.toByteArray(); // 获取完整数据
- 结果正确:所有数据被刷新到
ByteArrayOutputStream
,toByteArray()
能获取全部数据
情况2:先 toByteArray()
再 flush()
oos.writeUTF("fdjlfj");
oos.writeInt(123);
byte[] array = baos.toByteArray(); // 此时缓冲区可能未刷新
oos.flush(); // 刷新太晚,已无法影响之前的array
- 结果不完整:
toByteArray()
调用时,部分数据可能仍在ObjectOutputStream
的缓冲区中
3. 底层原理图示
[你的写入操作] → [ObjectOutputStream缓冲区] → [ByteArrayOutputStream] → [toByteArray()]
- 没有
flush()
:数据卡在ObjectOutputStream
缓冲区 - 调用
flush()
:数据完全进入ByteArrayOutputStream
4. 正确实践建议
(1)显式调用 flush()
在获取数据前强制刷新:
oos.writeUTF("test");
oos.flush(); // 确保数据写入底层流
byte[] data = baos.toByteArray();
(2)更安全的做法:关闭流
使用 try-with-resources 自动调用 flush()
和 close()
:
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeUTF("fdjlfj");
// 不需要手动flush,close()会自动调用flush()
byte[] array = baos.toByteArray();
}
(3)为什么 close()
也有效?
ObjectOutputStream.close()
内部会调用flush()
- 这是更可靠的写法(避免忘记手动刷新)
5. 总结
flush()
位置不同导致结果差异:是因为缓冲区的数据是否及时写入底层流- 最佳实践:
- 在
toByteArray()
前调用flush()
- 或使用 try-with-resources 自动管理
- 在
- 记忆口诀:
“包装流用完后,flush 要赶早,
或用 try-with-resources,省心又可靠。”