为什么我必须在C#中关闭()一个文件?
我知道这可能看起来很愚蠢,但为什么以下代码只有在我关闭()文件时才有效? 如果我不关闭文件,则不会写入整个流。
脚步:
- 在表单加载上运行此代码。
- 显示后,使用鼠标关闭表单。
- 程序终止。
当文件对象超出范围时,它不应该自动刷新或关闭吗? 我是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方法。