保持一个打开的StreamWriter作为类字段

本文关键字:StreamWriter 字段 一个 | 更新日期: 2023-09-27 17:58:08

我正试图编写一个类,该类将保持一个打开的StreamWriter,直到实例化的对象被销毁——这是为了避免常见的using习惯用法,因为在程序运行时,外部源不编辑文件是很重要的(因此FileShare.Read)。

一旦实例化,文件就会通过构造函数成功创建。对Write方法的调用实际上不会写入任何内容,也不会引发异常。一旦对象被销毁,析构函数就会在Cannot access a closed file.sw.Close()上抛出异常,即使BaseStream不是null。我不确定我是否理解其中的原因。

这个问题遵循了一些类似的方法,但在其他类型的类中。所以我认为这种方法应该有效,但无法确定为什么无效。

class SchemaWriter
{
    private StreamWriter sw;
    private string path;
    /// <summary>
    /// Creates an object to handle writing Schema.ini information
    /// </summary>
    /// <param name="Path">Path to place Schema.ini file in</param>
    public SchemaWriter(string Path)
    {
        path = Path;
        sw = new StreamWriter(File.Open(Path + "Schema.ini", FileMode.Create,
                              FileAccess.ReadWrite, FileShare.Read));
    }
    /// <summary>
    /// Writes Schema information about the supplied file name
    /// </summary>
    /// <param name="FileName">Name of file to write the Schema info about</param>
    public void Write(string FileName)
    {
        sw.WriteLine(String.Format(@"[{0}]", FileName));
        sw.WriteLine(@"Format=TabDelimited");
        sw.WriteLine();
    }
    /// <summary>
    /// Closes StreamWriter, deletes ini file
    /// </summary>
    ~SchemaWriter()
    {
        if(sw.BaseStream != null)
            sw.Close();
        File.Delete(path + @"Schema.ini");
    }
}

保持一个打开的StreamWriter作为类字段

GC已经声明(并处理了它)。您唯一应该做的就是实现IDisposable。执行以下操作:

class SchemaWriter : IDisposable
{
    private StreamWriter sw;
    public void Dispose()
    {
       sw.Dispose();
    }
    ...
}

您现在可以使用您的对象:

using(var writer = new SchemaWriter())
{
}

这将在处理完对象后立即关闭StreamWriter。如果你不使用using,GC会在你觉得合适的时候为你收集StreamWriter

使用using块的原因之一是StreamReaders/Writers是缓冲的,这样它们就不必为写入的每个字节重新访问硬盘。这意味着,在调用StreamWriter.Flush之前,您可能看不到实际输出到磁盘的数据。

我仍然会重新使用using块,但只是使用"保持打开"覆盖。参见:

http://msdn.microsoft.com/en-us/library/gg712853.aspx