所以我正在为学校项目尝试Windows表单并继续遇到错误:
System.IO.IOException('进程无法访问文件'C:\ XXXX \ YYYY.txt',因为它正由另一个进程使用。'
当试图通过File.Delete(path);
事件删除文件(button_click
)时。
事实证明,当我改变以下方法时:
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();
}
在你的第一种方法中,由于你不是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));
在第二个代码中,一旦您的代码块将执行,StreamReader将被处理掉。由于StreamReader将被丢弃,因此当前进程不会锁定该文件。
在您的第一个代码中,您可以通过在代码末尾处理它们来完成相同的操作。