C#:无法写入已关闭的TextWriter

时间:2013-04-24 20:25:51

标签: c#

为什么程序点击这里//这里。它与Unhandled Exception崩溃:System.ObjectDisposedException:无法写入已关闭的TextWriter。 在 LogClose()之前,Print()方法被称为。我想要实现的是如果它点击这里然后打印出消息并退出程序

foreach (string sf in ff)
{

    if (File.Exists(sf))
    {
        File.Move(sf, copy_dir + "\\" + sf);
    }
    else
    {
        //HERE
        l.ExitAndOut("Error: " + sf + " not found");
    }
}



class logger {
StreamWriter sw = new StreamWriter("SpireCli.log");

public void Print(string log)
{
    DateTime ts = DateTime.UtcNow;
    sw.WriteLine(ts + " " + log);
}

public void ExitAndOut(string log)
{
    string Program_Exit = "Program Exit";

    Console.WriteLine(log);
    Console.WriteLine(Program_Exit);
    Print(log);
    Print("Exit");
    LogClose();
    Environment.Exit(1);
}

public void LogClose()
{
    sw.Close();
}
}

3 个答案:

答案 0 :(得分:2)

如果我是你,我会使用Log4Net而不是重新发明轮子。 log4Net为您提供的一件事是能够一次将日志消息直接发送到多个数据存储。配置ConsoleAppender以及FileAppenderRollingFileAppender,您将获得控制台输出以及日志文件输出,以获得log.Warn()次呼叫的价格。

但是,如果您要自己滚动,那么日志文件的目的是以强大的方式记录事物:如果您将基础TextWriter及其Stream保持打开状态在没有在每次write()上刷新未写入的缓冲区的持续时间内,您可能会在发生崩溃时丢失数据。为此,像这样的班级应该为你做。它在每次写入时打开/关闭文件,确保事情处于有序状态:

class MyLogger
{
  private string LogFilePath { get ; set ; }
  public MyLogger( string fileName )
  {
    this.LogFilePath = fileName ;
    return ;
  }

  public void Print( string format , params object[] args )
  {
    using ( TextWriter logfile = new StreamWriter( "" , true , Encoding.UTF8 ) )
    {
      WriteLine( logfile , false , format , args ) ;
    }
    return ;
  }

  private void WriteLine( TextWriter writer , bool echoToConsole , string format , params object[] args )
  {
    string   message = string.Format( format , args ) ;
    DateTime dtNow   = DateTime.Now ;
    const string logFormat = "{0:yyyy-MM-dd hh:mm:ss.ttt}: {1}" ;
    writer.WriteLine( logFormat , dtNow , message ) ;
    if ( echoToConsole )
    {
      Console.WriteLine( logFormat , dtNow , message ) ;
    }
    return ;
  }

  public void ExitAndOut( string format , params object[] args )
  {
    using ( TextWriter logfile = new StreamWriter( "" , true , Encoding.UTF8 ) )
    {
      WriteLine( logfile , true , format , args ) ;
      WriteLine( logfile , true , "Program Exit" ) ;
    }
    Environment.Exit(1) ;
    return ; // unreachable code
  }

}

答案 1 :(得分:1)

你需要将代码重写为更像这样的东西(伪):

public static void Parse( )
{
   using( var sw = new StreamWriter(@"c:\file.txt") )
   { 
       foreach (string sf in ff)
       {
           if (File.Exists(sf))
              File.Move(sf, copy_dir + "\\" + sf);
           else
              Print( sw, "Error: " + sf + " not found");
       }
   }
}

public static void Print(StreamWriter s, string log)
{
    DateTime ts = DateTime.UtcNow;
    s.WriteLine(ts + " " + log);
}

答案 2 :(得分:1)

如果要关闭StreamWriter,则必须打开它。

class logger {

public void LogOpen()
{
    StreamWriter sw = new StreamWriter("SpireCli.log");
}

public void Print(string log)
{
    DateTime ts = DateTime.UtcNow;
    sw.WriteLine(ts + " " + log);
}

public void ExitAndOut(string log)
{
    string Program_Exit = "Program Exit";

    Console.WriteLine(log);
    Console.WriteLine(Program_Exit);
    LogOpen();
    Print(log);
    Print("Exit");
    LogClose();
    Environment.Exit(1);
}

public void LogClose()
{
    sw.Close();
}
}

由于StreamWriter实现了IDisposable,更好的方法是使用using语句。