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

Having some trouble to delete a file using FileStreams in C#

我正在用 C# 编写一个使用文本文件的程序。 我使用解析器 class 作为文件结构和程序之间的接口。 这个 class 包含一个 StreamReader、一个 StreamWriter 和一个 FileStream。我使用 FileStream 作为 reader 和 writer 的公共流,否则当它们都打开文件时这两者会发生冲突。

解析器 class 有一个名为 m_path 的 class 变量,这是文件的路径。我仔细检查过,路径是正确的。 OpenStreams()ResetStreams() 完美运行,但是在 delete() 函数中调用 CloseStreams() 后,程序会转到 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();

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

File.Delete 应该可以工作,要么你没有调用你的 delete 方法,要么 m_path 是一个无效路径

你的 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;
    }
}

例外是"Cannot access a closed file"

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

关闭 System.IO.StreamReader 对象和底层流,并释放与 reader.

关联的任何系统资源

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

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);

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

至少,你有一些样本可以开始......