【问题标题】:Why using using() {} around StreamReader.Read allows the file to be deleted afterwards?为什么在 StreamReader.Read 周围使用 using() {} 允许之后删除文件?
【发布时间】:2017-12-31 07:53:53
【问题描述】:

所以我在为一个学校项目试用 Windows 表单并一直遇到错误:

System.IO.IOException('进程无法访问文件'C:\XXXX\YYYY.txt',因为它正被另一个进程使用。'

尝试通过button_click 事件删除文件 (File.Delete(path);) 时。

原来,当我改变以下方法时:

private void updateTxt(){
  String tempStore = "";
  iDLbl1.Text = "ID:" + id;//iDLbl1 is ID Label 1
  try
  {
      StreamReader Reader = new StreamReader(path);
      while (!Reader.EndOfStream)
        { tempStore += Reader.ReadLine() + "\n"; }
  }
  catch { noIDLbl.Visible = true; }
  rTxtBox.Text = tempStore;//rTxtBox is Rich Text Box
} 

private void updateTxt(){
    String tempStore = "";
    iDLbl1.Text = "ID:" + id;//iDLbl1 is ID Label 1
    try
    {
        using(StreamReader Reader = new StreamReader(path))
        {
            while (!Reader.EndOfStream)
            { tempStore += Reader.ReadLine() + "\n"; }
        }

    }
    catch { noIDLbl.Visible = true; }
    rTxtBox.Text = tempStore;//rTxtBox is Rich Text Box
}

异常停止弹出。 虽然代码有效,但我根本不知道是什么原因造成的......逻辑似乎没有为我点击,所以任何人都知道为什么会发生这种情况或有更合乎逻辑的解决方案吗?如果需要请要求澄清,这是构造函数以防万一:

public FindID(String ID)
{
    id = ID;
    path = @"C:\XXXX\YYYY\"+ID+".txt";
    InitializeComponent();
    updateTxt();
}

【问题讨论】:

  • 是的,打开的文件需要再次关闭才能删除。您编写的代码不是 File.ReadAllText() 的有用替代品。

标签: c# winforms streamreader using system.io.file


【解决方案1】:

在您的第一种方法中,由于您不是 Close()ing 或 Dispose()ing 您的 StreamReader,因此相关的文件句柄将一直保留到垃圾收集器收集到 StreamReader,这可能是几秒钟,甚至几分钟后(请不要试图控制或影响 GC)。

在您的第二种方法中,using 作用域在作用域末尾处理(并关闭)StreamReader(关闭 } 匹配 using),这是使用任何类时的正确做法实现IDisposable。然后,这会释放文件的所有句柄,允许删除它。 using 块也有 try / finally 块的保证,所以即使有 IO 异常,Dispose 也会被调用:

using(StreamReader Reader = new StreamReader(path)) // try {StreamReader Reader = ...}
{
     ...
} <- equivalent to finally {Reader.Dispose();}

但是,由于您似乎只想立即将行分隔文本文件中的所有行具体化,您可以使用File.ReadAllLines 一步完成 - 即根本不需要StreamReader

var tempStore = string.Join(Environment.NewLine, File.ReadAllLines(path));

【讨论】:

    【解决方案2】:

    在第二个代码中,您的代码块将立即执行 StreamReader 将被释放。由于 StreamReader 将被释放,因此文件未被当前进程锁定。

    在您的第一个代码中,您可以通过在代码末尾处理它们来做同样的事情。

    【讨论】:

      猜你喜欢
      • 2012-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 2010-10-12
      • 1970-01-01
      • 2010-12-05
      相关资源
      最近更新 更多