在Java中,当我调用 OutputStream.close() 时,我是否总是需要调用 OutputStream.flush() ?

2022-08-31 22:33:36

如果我只是在输出流中调用,输出是有保证的,还是需要我一直调用?close()flush()


答案 1

虽然应该打电话,但它比这更复杂一些...closeflush

首先,装饰器(如)在Java中很常见。装饰器的构造可能会失败,因此您需要在包含装饰器的块中“原始”流。在异常的情况下,您通常不需要装饰器(例如,除了实现不良的压缩装饰器)。在非异常情况下,您通常需要装饰器。因此:BufferedOutputStreamclosefinallytrycloseflush

final RawOutputStream rawOut = new RawOutputStream(rawThing);
try {
    final DecoratedOutputStream out = new DecoratedOutputStream(rawOut);
    // ... stuff with out within ...
    out.flush();
} finally {
    rawOut.close();
}

最重要的是,装饰器方法的实现往往不正确。直到最近,这才包括一些。closejava.io

当然,您可能希望使用“围绕执行”(Execute Around)成语来保持 DRY(ish)。

编辑:从Java 8开始,您可以使用try-with-resource语句,这些语句应该很好地,简洁地处理所有事情。代码将在每个资源上调用 close,即使没有必要。

try (
    RawOutputStream rawOut = new RawOutputStream(rawThing);
    DecoratedOutputStream out = new DecoratedOutputStream(rawOut)
) {
    // ... stuff with out within ...
}

答案 2

Close() 始终刷新,因此无需调用。

编辑:这个答案是基于常识和我遇到的所有输出流。谁将在不先刷新缓冲区的情况下为缓冲流实现 close()?在 close() 之前调用 flush 是没有坏处的。但是,如果过度调用 flush() 会产生后果。它可能会破坏缓冲机制。