1

我的 C# 表单有一个问题。我有一个文本框,用于在单击外部 txt 文件的按钮时添加内容,以及一个显示 txt 文件内容的组合框。

我的代码:

String PathFile = @"Mypath";

private void button1_Click(object sender, EventArgs e)
{
    StreamWriter sw = new StreamWriter(PathFile);
    sw.WriteLine(textBox1.Text);
    sw.Close();
}

private void Form1_Load(object sender, EventArgs e)
{
    try
    {

        StreamReader sr = new StreamReader(PathFile);
        string line = sr.ReadLine();
        while (line != null)
        {
            comboBox1.Items.Add(line);
            line = sr.ReadLine();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error : " + ex.Message);
    }
}

组合框效果很好并显示了内容,但是当我尝试使用文本框添加新条目时,结果如下。

system.io.ioexception 进程无法访问该文件,因为它正被另一个进程使用

我知道文件被组合框的进程锁定,但我能做些什么来解决这种情况?

4

5 回答 5

9

您不会StreamReader在表单加载期间处理 。

using(StreamReader sr = new StreamReader(PathFile))
{
    string line = sr.ReadLine();
    while (line != null)
    {
        comboBox1.Items.Add(line);
        line = sr.ReadLine();
    }
}

此外,当您使用 将StreamWriter数据写入文件时,您还需要处理流:

using(StreamWriter sw = new StreamWriter(PathFile))
{ 
    sw.WriteLine(textBox1.Text);
}

那么做using什么呢?这是一个相当整洁的结构。无论代码到达块的末尾还是抛出异常,它都需要IDisposable并确保对象被释放。using我们需要处理流之类的东西,因为它们拥有非托管资源(例如文件句柄),我们不想等待垃圾收集器启动并实际释放句柄。

using在语义上等价于:

IDisposable someObjectThatIsDispoable; // e.g. StreamWriter/StreamReader, et al
try
{
     // your code here
}
finally
{
    if(someObjectThatIsDisposable != null)
        someObjectThatIsDisposable.Dispose();
}

此外, dispose 负责关闭文件,因此调用Close是不必要的(因此它们已从此答案中删除)。

于 2013-07-26T15:19:05.180 回答
4

打开/关闭 Stream 的正确方法是通过using 语句

在你的 Form_Load

 using(StreamReader sr = new StreamReader(PathFile))
 {
    string line = sr.ReadLine();
    while (line != null)
    {
        comboBox1.Items.Add(line);
        line = sr.ReadLine();
    }
 }

这将确保 StreamReader 在右大括号处的正确关闭和处置,即使在 using 块内出现异常的情况下

当然,您也应该以同样的方式更改 Button_Click 代码

private void button1_Click(object sender, EventArgs e)
{
    using(StreamWriter sw = new StreamWriter(PathFile))
    {
         sw.WriteLine(textBox1.Text);
    }
    // No really needed to call close
}
于 2013-07-26T15:20:29.247 回答
3

如其他答案中所述,您收到该错误是因为您的流未关闭。但是,您可以避免显式使用 a ,也可以改用File.ReadAllLinesStreamReader来缩短代码。

try
{
    foreach(string line in File.ReadAllLines(PathFile))
    {
       comboBox1.Items.Add(line);           
    }

}
catch (Exception ex)
{
    MessageBox.Show("Error : " + ex.Message);
}

虽然不一定,但using在处理实现IDisposable. 所以对于你的StreamWriter,你可以使用这个

using(StreamWriter sw = new StreamWriter(PathFile))
{
   sw.WriteLine(textBox1.Text);
}

这确保了流被关闭并且StreamWriter对象被释放。

于 2013-07-26T15:25:09.617 回答
1

StreamWriter通过调用load 方法的 dispose 释放文件。

private void Form1_Load(object sender, EventArgs e)
{
    StreamReader sr = new StreamReader(PathFile);
    try
    {
        string line = sr.ReadLine();
        while (line != null)
        {
            comboBox1.Items.Add(line);
            line = sr.ReadLine();
        }
        sr.Dispose();
        sr = null; 
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error : " + ex.Message);
    }
    finally //Just in case any exception is thrown.
    {
       if (sr != null)
           sr.Dispose();
           sr = null;
    }
}
于 2013-07-26T15:19:34.117 回答
1

你没有处理StreamReader. 尝试这个:

private void Form1_Load(object sender, EventArgs e)
{
    StreamReader sr = null; // declare the StreamReader outside the try-catch-finally block
    try
    {

        sr = new StreamReader(PathFile);
        string line = sr.ReadLine();
        while (line != null)
        {
            comboBox1.Items.Add(line);
            line = sr.ReadLine();
        }

    }
    catch (Exception ex)
    {
        MessageBox.Show("Error : " + ex.Message);
    }
    finally
    {
        if (sr != null)
        {
             sr.Dispose(); // dispose the StreamReader if it's not null
        }
    }
}
于 2013-07-26T15:22:02.643 回答