using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
を使用すると上記のエラーメッセージが表示されるのに、fileStream = File.Create(path);
に置き換えるとプログラムが完全に実行されるのはなぜですか?
コンソール出力を外部ファイルに追加したい。これが私のコードです:
_ //copy console output to file in bin\Debug folder
class ConsoleCopy : IDisposable
{
FileStream fileStream;
StreamWriter fileWriter;
TextWriter doubleWriter;
TextWriter oldOut;
class DoubleWriter : TextWriter
{
TextWriter one;
TextWriter two;
public DoubleWriter(TextWriter one, TextWriter two)
{
this.one = one;
this.two = two;
}
public override Encoding Encoding
{
get { return one.Encoding; }
}
//Clears all buffers for the current writer
public override void Flush()
{
one.Flush();
two.Flush();
}
public override void Write(char value)
{
**one.Write(value);**//error thrown here
two.Write(value);
}
}
public ConsoleCopy(string path)
{
oldOut = Console.Out;
try
{
**//fileStream = File.Create(path);** //runs alright with this line
fileWriter = new StreamWriter(fileStream);
fileWriter.AutoFlush = true;
doubleWriter = new DoubleWriter(fileWriter, oldOut);
}
catch (Exception e)
{
Console.WriteLine("Cannot open file for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(doubleWriter);
}
public void Dispose()
{
Console.SetOut(oldOut);
if (fileWriter != null)
{
fileWriter.Flush();
fileWriter.Close();
fileWriter = null;
}
if (fileStream != null)
{
fileStream.Close();
fileStream = null;
}
}
}//end of consoleCopy
_
私はこのメソッドをメインメソッドで次のように呼び出します。
_ //pass output to ConsoleCopy method for copying to .txt file
using (var cc = new ConsoleCopy("mylogfile.txt"))
{
DateTime theDate = DateTime.UtcNow;
string custom = theDate.ToString("d");
Console.WriteLine("User has logged in on " + custom);
}
_
更新:
エラーは以前はone.Write(value)
で示されていました。ピーターのおかげでなんとか解決できました。あなたの貢献と助けをみんなに感謝します:)
編集:書く前にそれを取得している場合、それは私が質問を読み間違えたためであり、ConsoleCopyコンストラクターにusingステートメントを置くことは、ConsoleCopyの作成が終了するとFileStreamが閉じられることを意味します。あなたがそれに書き込もうとする時までに、それはすでに閉じられているので、あなたはその例外を受け取ります。同じ解決策が適用されます。FileStreamを開いたままにして、Dispose()で閉じます。ここで、mainメソッドのusingステートメントを使用します。
私が正しく理解していれば、処分時にその例外が発生しますよね?もしそうなら、それはあなたがそのストリームを2回閉じているということが本質的に起こっているからです。
using (var cc = new ConsoleCopy("mylogfile.txt"))
{
// At this time, your filestream is created with the using statement.
// Writing happens here.
// Your filestream is closed at the end of the using statement inside of the ConsoleCopy constructor.
}
// At this point, ConsoleCopy tries to call Dispose(), which flushes and closes everything again. However, this throws an exception because the using statement already closed the FileStream.
ファイルの末尾に追加することが目標であり、Dispose()メソッドがすべてを内部的に閉じる場合は、単に置き換えるだけではどうでしょうか。
**//fileStream = File.Create(path);** //runs alright with this line
と
fileStream = File.Open(path, System.IO.FileMode.Append, System.IO.FileAccess.Write);
メインのusingステートメントでストリームを内部的に閉じますか?
using
ステートメントの外で書き込みコードを実行していますか?ストリームを操作する前に、ストリームを閉じている可能性があります。
これを実行するとどうなりますか:
using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
{
fileWriter = new StreamWriter(fileStream);
fileWriter.AutoFlush = true;
doubleWriter = new DoubleWriter(fileWriter, oldOut);
}