如果您使用“using”语句,是否需要在流或写入器上调用Flush()?

50

我不确定在像这样写东西时是否需要调用使用的对象上的 Flush()

using (FileStream...)
using (CryptoStream...)
using (BinaryWriter...)
{
    // do something
}

它们是否总是自动刷新?什么时候using语句会刷新它们,什么时候不会(如果可能的话)?

2个回答

63

一旦您离开使用块的范围,流就会关闭和处理。Close()调用Flush(),因此您不需要手动调用它。


9
不必要,Dispose总是会关闭流,而Close会先刷新流。 - nos
1
@FelixCzylwik:如果使用结束后没有调用Close,你会有大量的未关闭流和SQLConnections存在... :D - Davide Piras
1
@FelixC 编译器不需要的许多东西在提高可读性的过程中仍然很有帮助。 - Robino
1
相关:Stream.Dispose是否总是调用Stream.Close,以及一个注意事项,即隐式刷新只是通常行为,不是由Stream类本身实现的(因此在扩展时要小心)。 - Palec
@Robino - 我曾经手动添加close(),和你的想法类似。但是在一个大项目中,有时我或另一个程序员没有放置关闭语句。这就导致了不确定是否需要在那里添加关闭语句。更糟糕的是,有时程序员觉得他们需要执行flush然后执行close。最终我删除了所有不需要的flushclose()行。一致的编码和了解系统如何工作(“使用意味着Dispose意味着Close意味着Flush”)也是“可读性”的一部分。 - ToolmakerSteve
显示剩余2条评论

-4

这个问题是不确定的,Stream默认情况下在Dispose方法中不会调用Flush(),但有一些例外,比如FileStream。原因是某些流对象不需要调用Flush,因为它们不使用缓冲区。有些流对象,例如MemoryStream,明确重写该方法以确保不执行任何操作(使其成为无操作)。
这意味着,如果您不想在其中添加额外的调用,则应检查您正在使用的Stream子类是否在Dispose方法中实现了该调用,以及是否有必要。

无论如何,出于可读性的考虑,最好还是调用它 - 就像有些人在使用语句结尾处调用Close()一样:

using (FileStream fS = new FileStream(params))
using (CryptoStream cS = new CryptoStream(params))
using (BinaryWriter bW = new BinaryWriter(params))
{
    doStuff();
    //from here it's just readability/assurance that things are properly flushed.
    bW.Flush();
    bW.Close();
    cS.Flush();
    cS.Close();
    fS.Flush();
    fS.Close();
}

3
我认为添加flush和close调用会对可读性和可维护性造成负面影响。使用using语句可以确保对象在出现异常时被正确释放。 - Palec
@Palec 我理解你的立场,这是我见过的许多开发人员之间的一个分歧标准。 - IAmJersh
@Palec 另外,正如我在答案中所述 - 流默认不会在其处理方法中调用 Flush() 方法,这意味着如果您正在使用某人创建的非标准流,并且该人员尚未考虑到这一点,则 using 语句将无法正确刷新缓冲区。因此,我认为手动刷新是一个好习惯 - 如果不需要任何操作,它就不会做任何事情,但如果需要,则会确保正确处理缓冲区。 - IAmJersh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接