关于 flush() 位置影响导致结果不同的解释

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(); // 获取完整数据
  • 结果正确:所有数据被刷新到 ByteArrayOutputStreamtoByteArray() 能获取全部数据

情况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() 位置不同导致结果差异:是因为缓冲区的数据是否及时写入底层流
  • 最佳实践
    1. toByteArray() 前调用 flush()
    2. 或使用 try-with-resources 自动管理
  • 记忆口诀

    “包装流用完后,flush 要赶早,
    或用 try-with-resources,省心又可靠。”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步行cgn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值