为什么我必须在C#中关闭()一个文件?

我知道这可能看起来很愚蠢,但为什么以下代码只有在我关闭()文件时才有效? 如果我不关闭文件,则不会写入整个流。

脚步:

  1. 在表单加载上运行此代码。
  2. 显示后,使用鼠标关闭表单。
  3. 程序终止。

当文件对象超出范围时,它不应该自动刷新或关闭吗? 我是C#的新手,但我习惯在C ++析构函数中添加对Close()的调用。

// Notes: complete output is about 87KB. Without Close(), it's missing about 2KB at the end. // Convert to png and then convert that into a base64 encoded string. string b64img = ImageToBase64(img, ImageFormat.Png); // Save the base64 image to a text file for more testing and external validation. StreamWriter outfile = new StreamWriter("../../file.txt"); outfile.Write(b64img); // If we don't close the file, windows will not write it all to disk. No idea why // that would be. outfile.Close(); 

C#没有自动确定性清理。 如果要控制运行时,必须确保调用清理function。 using块是最常用的方法。

如果你没有自己进行清理调用,那么当垃圾收集器决定其他东西需要内存时会发生清理,这可能需要很长时间。

 using (StreamWriter outfile = new StreamWriter("../../file.txt")) { outfile.Write(b64img); } // everything is ok, the using block calls Dispose which closes the file 

编辑:正如哈维指出的那样,当对象被收集时将尝试进行清理,但这并不能保证成功。 为了避免循环引用的问题,运行时不会尝试以“正确”顺序完成对象,因此在StreamWriter终结器运行并尝试刷新缓冲输出时, FileStream实际上已经死了。

如果处理需要清理的对象,可以using (对于本地作用域)或通过调用IDisposable.Dispose (对于长期存在的对象,例如类成员的指示对象)进行显式处理。

因为Write()被缓冲并且缓冲区被Close()显式刷新。

流是“管理”或“处理”非垃圾收集资源的对象。 因此,它们(Streams)实现了IDisposable接口,当与’using’一起使用时,将确保清理非垃圾收集的资源。 试试这个:

 using ( StreamWriter outfile = new StreamWriter("../../file.txt") ) { outfile.Write(b64img); } 

没有#Close,您无法确定何时正确关闭基础文件句柄。 有时候,这可以在app关闭。

因为您正在使用一个流写器,并且在您Close()编写器之前它不会刷新缓冲区。 通过将streamwriter的AutoFlush属性设置为true,可以指定希望编写器在每次调用write时进行刷新。

查看文档。 http://msdn.microsoft.com/en-us/library/system.io.streamwriter.aspx

如果你想写一个没有“关闭”的文件,我会使用:

 System.IO.File 

操作系统缓存写入块设备以使OS具有更好的性能。 在将写入器设置为autoflush后,通过刷新缓冲区强制写入。

因为C#设计者在克服Java而不是C ++,尽管名称。

在我看来他们真的错过了这条船。 范围退出时的C ++样式破坏会好得多

它甚至不必释放内存更好,只需自动运行终结器或IDisposable方法。