文件流 "cannot access closed file"
FileStream "cannot access closed file"
为什么我在使用 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)
。多亏了彼得,我已经设法解决了它。感谢大家的贡献和帮助:)
您是否运行正在 using
语句之外编写代码?您可能在对其进行任何操作之前关闭了流。
当你运行这个时会发生什么:
using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
{
fileWriter = new StreamWriter(fileStream);
fileWriter.AutoFlush = true;
doubleWriter = new DoubleWriter(fileWriter, oldOut);
}
编辑:如果您在编写之前得到它,那是因为我误读了问题,将 using 语句放在 ConsoleCopy 构造函数中意味着当 ConsoleCopy 完成创建时,FileStream 将关闭。当您尝试写入它时,因为它已经关闭,您会得到该异常。相同的解决方案将适用 - 让 FileStream 打开并在 Dispose() 中关闭它,它应该与 main 方法中的 using 语句一起使用。
如果我没理解错的话,你会得到处理异常,对吧?如果是这样,那是因为发生的事情本质上是您关闭了该流两次。
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);
并让 main 中的 using 语句在内部为您关闭流?
为什么我在使用 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)
。多亏了彼得,我已经设法解决了它。感谢大家的贡献和帮助:)
您是否运行正在 using
语句之外编写代码?您可能在对其进行任何操作之前关闭了流。
当你运行这个时会发生什么:
using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))
{
fileWriter = new StreamWriter(fileStream);
fileWriter.AutoFlush = true;
doubleWriter = new DoubleWriter(fileWriter, oldOut);
}
编辑:如果您在编写之前得到它,那是因为我误读了问题,将 using 语句放在 ConsoleCopy 构造函数中意味着当 ConsoleCopy 完成创建时,FileStream 将关闭。当您尝试写入它时,因为它已经关闭,您会得到该异常。相同的解决方案将适用 - 让 FileStream 打开并在 Dispose() 中关闭它,它应该与 main 方法中的 using 语句一起使用。
如果我没理解错的话,你会得到处理异常,对吧?如果是这样,那是因为发生的事情本质上是您关闭了该流两次。
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);
并让 main 中的 using 语句在内部为您关闭流?