【问题标题】:Why is it necessary to flush the output buffer when it was just created?为什么在刚刚创建输出缓冲区时需要刷新它?
【发布时间】:2014-04-04 10:16:15
【问题描述】:

在以下场景中

ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
output.flush();
// Do stuff with it

为什么在初始创建后总是需要刷新缓冲区?
我一直都看到这种情况,但我真的不明白 什么 必须刷新。除非另有说明,否则我希望新创建的变量为空。

有点像买一个垃圾桶,然后在里面发现一小堆垃圾。

【问题讨论】:

标签: java io flush


【解决方案1】:

在超过 15 年的专业 Java 编写经验中,我从未遇到过在写入流之前需要刷新流的情况。
刷新操作根本不会做任何事情,因为没有什么要刷新的。
您想在关闭流之前刷新流,尽管关闭操作应该为您执行此操作,但通常认为明确地执行此操作是最佳实践(我遇到过确实会产生影响的情况,显然关闭操作实际上并没有先冲洗一下。
也许你对此感到困惑?

【讨论】:

  • 我不会混淆初始创建后的刷新与关闭流之前的刷新。我一直相信,在检索到 OutputStream 对象后,有些东西从一开始就驻留在缓冲区中。我只是想知道什么以及它为什么会出现。
【解决方案2】:

当您将数据写入流时,会发生一定量的缓冲,您永远无法确切知道最后一个数据何时实际发送。您可以在关闭流之前对流执行许多 rite 操作,并且调用 flush() 方法可以确保您认为已经写入的最后一个数据实际上会输出到文件中。每当您使用完一个文件,无论是读取它还是写入它,您都应该调用 close() 方法。当您进行文件 I/O 时,您正在使用昂贵且有限的操作系统资源,因此当您完成后,调用 close() 将释放这些资源。

【讨论】:

  • 我不确定这是否解释了为什么必须在 执行任何写入操作之前刷新输出流。
  • 写入流之后是的,但是在初始创建之后呢?在写任何东西之前,我没有看到同样的情况发生。
  • 是的,但似乎与问题无关。 OP 询问为什么流在创建后需要立即刷新(其中不应该有任何数据)。
  • 读取文件时,不需要刷新,因此您甚至不会在 Reader 类中找到 flush() 方法。对于所有输出文件,您可能会发现缓冲区没有'不会被刷新,因此文件将不完整,您可能看不到输出。
【解决方案3】:

在使用ObjectInputStreamObjectOutputStream 时需要这样做,因为它们会在调用第一次写入之前通过流发送标头。对flush() 的调用会将该标头发送到远程端。

根据spec,头部存在以下内容:

magic version

如果在构建 ObjectInputStream 时标头未到达,则此调用将挂起,直到收到标头字节。

这意味着如果有问题的协议是用ObjectStreams 编写的,它应该在创建ObjectOutputStream 后刷新。

【讨论】:

    猜你喜欢
    • 2022-10-02
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 2011-10-31
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多