我有以下代码来读取和写入一行文本文件。我们可以在处理结束时为阅读器和编写器对象分配null吗?或者我应该调用Close()方法?谢谢。
FileInfo JFile = new FileInfo(@"C:\test.txt");
using (FileStream JStream = JFile.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
StreamReader reader = null;
StreamWriter writer = null;
try
{
int n;
reader = new StreamReader(JStream);
string line = reader.ReadLine();
int.TryParse(line, out n);
n = n + 1;
writer = new StreamWriter(JStream);
JStream.Seek(0, SeekOrigin.Begin);
writer.WriteLine(n);
writer.Flush();
}
catch (Exception x)
{
string message = string.Format("Error while processing the file. {0}", x.Message);
System.Windows.Forms.MessageBox.Show(message);
}
reader = null;
writer = null;
}
答案 0 :(得分:4)
关闭文件时需要进行某些操作。例如,当您的程序访问文件并在其上创建handle时。 .Close()
- 流允许框架立即释放句柄和其他类似资源。
当您将其设置为null
时,您依靠垃圾收集器为您执行此重要功能。 GC现在可以清理它,或者它可能不会。你不知道什么时候会发生。如果您的程序崩溃,它可能永远不会释放句柄。
一旦你完成了.Close()
流,你总是一个好主意。
答案 1 :(得分:2)
您应该调用Close方法,以便释放所有基础非托管资源。将对象设置为null,不会释放资源。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.io.stream.close.aspx
更新:由于您的代码在using语句中,因此在使用语句内部执行完成后,将自动调用Dispose方法。
答案 2 :(得分:2)
当您将对象设置为null时,您告诉CLR您不再需要它并且它被安排用于垃圾收集。您将遇到的问题是,在您的程序结束并且CLR关闭之前,CLR与您打开的文件的挂钩不会被释放。当您调用Close()方法时,将清理文件资源,然后正确安排垃圾收集的位数。
如果你在一个使用块中打开streamreader,它也将为你处理这个问题,但是你放弃了一些使用try / catch / finally块获得的细粒度错误处理。
答案 3 :(得分:1)
StreamReader
和StreamWriter
实施IDisposable
,这是他们的说法
“当你完成我的时候,请拨打这个方法(
Dispose()
),这样我就知道你已经完成了我,我可以自我清理”。
(这也称为确定性终结)
所以你需要在那些上调用Dispose
,或者将它们包装在using
语句中,这对你做同样的事情。对于这两个类,如果Dispose
尚未关闭,Close
会在内部调用{{1}}。
答案 4 :(得分:1)
您实际上想要调用Close()或更好的Dispose()以确保刷新所有内容。如果您没有明确关闭/处置Writer,则可能无法写入缓冲区。
答案 5 :(得分:1)
我认为最好的解决方案是使用using
语句(就像你在FileStream
中所做的那样)。
它会照顾所有的清洁工作。