1

私の C# フォームには 1 つの問題があります。ボタンをクリックして外部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();
    }
 }

これにより、using ブロック内で例外が発生した場合でも、右中括弧で StreamReader を適切に閉じて破棄することが保証されます。

もちろん、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

を処分しませんでした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 に答える
1

StreamWriterload メソッドの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 に答える