web-dev-qa-db-ja.com

StreamWriterクラスを適切に使用する方法は?

ファイル操作にStreamWriterクラスを使用していますが、このコードに表示されていない問題はありますか?

try catch finallyブロックに入れる必要がありますか?

StreamWriter sr = new StreamWriter(streamFolder);
sr.Write(details);

File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();
9
vettori

コードの何が問題になっていますか?ストリームを閉じる前に何らかの例外が発生した場合、ストリームは開いたままになり、システムリソースは解放されません。

_StreamWriter sr = new StreamWriter(streamFolder);
sr.Write(details);
// some exception occurs here 
File.SetAttributes(streamFolder, FileAttributes.Hidden);
sr.Close();
_

したがって、そのストリームが閉じられることを確認する必要があります。これは、_try...finally_ブロックによって実現できます。

_StreamWriter sr = new StreamWriter(streamFolder);

try 
{
   sr.Write(details);
   // some exception occurs here 
   File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
finally
{
   sr.Close();
}
_

ただし、StreamWriterは IDisposable インターフェイスを実装しているため、ライターの使用状況をusingブロックにラップすることで、C#コンパイラに自動的に実行させることができます。

_using(StreamWriter sr = new StreamWriter(streamFolder)) 
{
   sr.Write(details);
   // some exception occurs here 
   File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
_

このコードは次のようにコンパイルされます。

_StreamWriter sr = new StreamWriter(streamFolder);

try 
{
   sr.Write(details);
   // some exception occurs here 
   File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
finally
{
   if (sr != null)
      sr.Dispose();
}
_

手動実装の唯一の違いはnullチェックであり、メソッドDisposeCloseの代わりに呼び出されます。ただし、実際にはClose()またはDispose()を呼び出すと、同じコードが実行されます。

_this.Dispose(true);
GC.SuppressFinalize(this);
_

詳細については、 メソッドの実装を破棄 を参照してください。

30

おそらくusingステートメントを使用する必要があります。

using (StreamWriter sr = new StreamWriter(streamFolder))
{
    sr.Write(details);
    File.SetAttributes(streamFolder, FileAttributes.Hidden);
}

Usingブロックの最後に、例外があったかコードが正常に実行されたかに関係なく、StreamWriter.Disposeが呼び出されます。

6

使用したい:

  using (StreamWriter sr = new StreamWriter(streamFolder))
  {
      sr.Write(details); 

      File.SetAttributes(streamFolder, FileAttributes.Hidden); 
  }

Closeは必要ありません。

5
John Saunders

usingブロックでラップします

using(StreamWriter sr = new StreamWriter(streamFolder))
{
      sr.Write(details);
      File.SetAttributes(streamFolder, FileAttributes.Hidden);
}

名前が適切であることを確認してください。したがって、streamFolderはおそらくfNameであるはずです。いくつかのIO(または他の)例外)を処理できると思われる場合は、このコードをtry-catch-finallyに入れることもできます。

StreamWriter sr;
try
{
    sr = new StreamWriter(streamFolder);
    sr.Write(details);
    File.SetAttributes(streamFolder, FileAttributes.Hidden);
}
catch(IOException ex)
{
    //handling IO
}
finally
{
    if (sr != null)
        sr.Dispose();
}
5
oleksii