关闭FileStream并将其设置为null有什么区别?

时间:2011-05-06 17:49:44

标签: c#-3.0

我有以下代码来读取和写入一行文本文件。我们可以在处理结束时为阅读器和编写器对象分配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;
            }

6 个答案:

答案 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)

StreamReaderStreamWriter实施IDisposable,这是他们的说法

  

“当你完成我的时候,请拨打这个方法(Dispose()),这样我就知道你已经完成了我,我可以自我清理”。

(这也称为确定性终结

所以你需要在那些上调用Dispose,或者将它们包装在using语句中,这对你做同样的事情。对于这两个类,如果Dispose尚未关闭,Close会在内部调用{{1}}。

答案 4 :(得分:1)

您实际上想要调用Close()或更好的Dispose()以确保刷新所有内容。如果您没有明确关闭/处置Writer,则可能无法写入缓冲区。

答案 5 :(得分:1)

我认为最好的解决方案是使用using语句(就像你在FileStream中所做的那样)。 它会照顾所有的清洁工作。