在C#中使用FileStreams删除文件时遇到一些麻烦

时间:2015-04-23 00:11:54

标签: c# file filestream

我正在编写一个在C#中使用文本文件的程序。 我使用解析器类作为文件结构和程序之间的接口。 此类包含StreamReaderStreamWriterFileStream。我使用FileStream作为读者和作者的公共流,否则这两者在两个文件都打开时都会发生冲突。

解析器类有一个名为m_path的类变量,这是该文件的路径。我已经进行了广泛的检查,路径是正确的。 OpenStreams()ResetStreams()工作正常,但在CloseStreams()函数中调用delete()后,程序转到catch子句,因此File.Delete(m_path)将无法获取执行。在其他情况下,CloseStreams()功能完美运行。当我试图关闭StreamReader (m_writer)时会出错,但它确实会出现异常(文件已经关闭)。

   /**
     * Function to close the streams.
     */
    private void closeStreams() {
        if (m_streamOpen) {
            m_fs.Close();
            m_reader.Close();
            m_writer.Close(); // Goes wrong

            m_streamOpen = false;
        }
    }

   /**
     * Deletes the file.
     */
    public int delete() {
        try {
            closeStreams(); // Catch after this
            File.Delete(m_path);

            return 0;
        }
        catch { return -1; }
    }

我这样称呼函数:

parser.delete();

有人可以给我一些提示吗?

2 个答案:

答案 0 :(得分:0)

File.Delete应该有效,要么您没有调用delete方法,要么m_path是无效路径

答案 1 :(得分:0)

您的File.Delete(m_path);永远不会被调用,因为您在此处获得例外:

private void closeStreams() {
    if (m_streamOpen) {
        m_fs.Close();
        m_reader.Close();
        m_writer.Close(); // throws an exception here

        m_streamOpen = false;
    }
}

例外是“无法访问已关闭的文件”

Close()中的StreamReader文档中解释了原因:

关闭System.IO.StreamReader对象和基础流,并释放与阅读器关联的所有系统资源。

还有一些关于此行为的文章:

Does disposing streamreader close the stream?

Is there any way to close a StreamWriter without closing its BaseStream?

Can you keep a StreamReader from disposing the underlying stream?

Avoiding dispose of underlying stream

您应该考虑重新编写代码并使用using()语句。

但是,我对您的代码进行了一些实验,并以其他顺序调用Close()

m_writer.Close();
m_reader.Close();
m_fs.Close();

但是,我认为这只能巧合(我使用的是.NET 4.0,可能这在另一个.NET版本中不起作用)。我强烈建议不要这样做。

我测试了这个:

using (FileStream fs = new FileStream(m_path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (StreamReader reader = new StreamReader(fs))
using (StreamWriter writer = new StreamWriter(fs))
{
  // so some work here

}

File.Delete(m_path);

但是,我知道这可能不适合您,因为您可能希望读取和写入流可用作您班级中的字段。

至少,你有一些样品开始......