3

我有一个类,它从一个文件流中读取数据并写入另一个文件流。我担心在 closeFiles() 中处理完成后关闭流。

您将如何处理一个流的 dispose 可能引发异常以阻止另一个流的 dispose 被调用的可能性。

我应该调用 close 并处理流还是只处理一个?

如果我从流处理中捕获任何错误,然后继续移动和删除文件,如 lastOperation() 所示,会发生什么?

在一个完美的世界中,我想在 c++ 样式初始化列表中使用 using 语句,但我很确定这在 c# 中是不可能的。

编辑:感谢你们的快速回复。所以我应该做的是从 IDisposable 派生,然后更改构造函数并添加两个这样的处理方法?:

    ~FileProcessor()
    {
        Dispose(true);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                sw.Flush();
            }
            closeFiles();
            disposed = true;
        }
    }

这基本上就是我正在做的事情:

class FileProcessor
{
    private string in_filename;
    private string out_filename;
    private StreamReader sr;
    private StreamWriter sw;
    bool filesOpen = false;

    public FileProcessor(string filename)
    {
        in_filename = filename; 
        out_filename = filename + ".out";
        openFiles();
    }

    ~FileProcessor()
    {
        closeFiles();
    }

    private void openFiles()
    {
        sr = new StreamReader(in_filename);
        sw = new StreamWriter(out_filename);
        filesOpen = true;
    }

    private void closeFiles()
    {
        if (filesOpen)
        {
            sr.Close();
            sw.Close();
            sr.Dispose();
            sw.Dispose();
            filesOpen = false;
        }
    }

    /* various functions to read, process and write to the files */

    public void lastOperation()
    {
        closeFiles();
        File.Delete( in_filename );
        Directory.Move(out_filename, outdir + out_filename);
    }
}
4

4 回答 4

3

IDisposable如果您在其中使用 IDisposable 对象,我认为让您的类实现接口是一个好习惯。

然后,您应该确保在您的Dispose()实现中不要抛出异常。如果您处置的每个物品都做出此保证,您的客户将是安全的。

于 2010-11-29T10:20:03.087 回答
3

您的 FileProcessor 类不应有析构函数。它没有用,但是很贵。

它应该有一个Dispose()(并实现 IDisposable 接口)来调用 closeFiles()。

就像@marcelo 回答的那样, Stream.Dispose() 不应该抛出。对于 BCL 类,您可以依赖它。

但是您应该检查每个 Reader/Writer 是否为空,以防第一个打开但第二个失败:

if (sr != null) sr.Dispose();
if (sw != null) sw.Dispose();

filesOpen不能同时涵盖两者。

于 2010-11-29T10:20:14.040 回答
2

Dispose 方法不应该抛出异常。甚至还有一个代码分析工具警告

于 2010-11-29T10:17:41.490 回答
0

在 C# 中,using确实存在。提供给 using 语句的对象必须实现 IDisposable 接口。该接口提供了 Dispose 方法,该方法应该释放对象的资源。

如果您的 StreamReader 和 StreamWriter 实现了 IDisposable,您可以将它们放在 using 块中,当您完成它们时,它们将被干净地处理掉。

using(var sr = new StreamReader(in_filename)) {
    // Perform reader actions
}
// Reader will now be disposed.
于 2010-11-29T10:18:58.217 回答