在其生命周期结束时刷新 StreamWriter
Flush StreamWriter at the end of its lifetime
我有一个类似单例的 class 可以做一些日志输出:
class Foo
{
private static Foo instance;
private System.IO.StreamWriter os;
private Foo()
{
this.os = System.IO.File.CreateText( "D:/tmp/test" );
}
public static Foo Instance
{
get
{
if ( instance == null )
instance = new Foo();
return instance;
}
}
public void Log( string s )
{
os.Write( s );
}
}
当我在像
这样的示例程序中使用它时
class Program
{
private static void Main( string[] args )
{
Foo.Instance.Log( "asdf\n" );
}
}
正在创建文件,但未写入任何输出。我认为这是因为 StreamWriter
从未被刷新过。
我试图通过调用 ~Foo()
中的 Close()
来修复 class:
~Foo()
{
os.Close();
}
但这会产生 ObjectDisposedException
。显然,当 Foo
的析构函数被调用时,Foo.os
已经被释放了。
如何确保我的 StreamWriter
被刷新 "at last"?
编辑
设置 this.os.AutoFlush = true;
有效。将 Flush()
方法添加到 Foo
并在适当的地方调用它也是如此,但我很感兴趣是否有任何方法可以不用。
您可以使用具有 Flush 方法的 StreamWriter。
对于您要完成的任务,还有另一种选择,您可以使用 File.AppendAllText 并且会起作用。这样就不会一直打开StreamWriter
class Foo
{
private static Foo instance;
private System.IO.StreamWriter os;
private Foo()
{
this.os = new System.IO.StreamWriter("D:/tmp/test.txt");
}
public static Foo Instance
{
get
{
if (instance == null)
instance = new Foo();
return instance;
}
}
public void Log(string s)
{
os.WriteLine(s);
os.Flush();
}
public void Log2(string s)
{
System.IO.File.AppendAllText(@"D:/tmp/test2.txt",s);
}
}
首先,使用单例本身就会产生问题,这不需要其他证明。在这里,它是对伪装的全局的清理。 StreamWriter
不会在程序结束时根据 the documentation、
自动刷新
You must call Close to ensure that all data is correctly written out to the underlying stream.
感谢@PeterDuniho 对“”的回答,可能的解决方案是将构造函数更改为
private Foo()
{
this.os = System.IO.File.CreateText( "D:/tmp/test" );
System.AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => this.os.Close();
}
考虑到在析构函数中调用Close()
的问题,我不应该忽略到处写的"finalizers are not of much use anyway"。在这种情况下,由于垃圾回收没有使用特定的顺序,StreamWriter
对象已经被回收并且无法在其复活的僵尸状态下关闭。
我有一个类似单例的 class 可以做一些日志输出:
class Foo
{
private static Foo instance;
private System.IO.StreamWriter os;
private Foo()
{
this.os = System.IO.File.CreateText( "D:/tmp/test" );
}
public static Foo Instance
{
get
{
if ( instance == null )
instance = new Foo();
return instance;
}
}
public void Log( string s )
{
os.Write( s );
}
}
当我在像
这样的示例程序中使用它时class Program
{
private static void Main( string[] args )
{
Foo.Instance.Log( "asdf\n" );
}
}
正在创建文件,但未写入任何输出。我认为这是因为 StreamWriter
从未被刷新过。
我试图通过调用 ~Foo()
中的 Close()
来修复 class:
~Foo()
{
os.Close();
}
但这会产生 ObjectDisposedException
。显然,当 Foo
的析构函数被调用时,Foo.os
已经被释放了。
如何确保我的 StreamWriter
被刷新 "at last"?
编辑
设置 this.os.AutoFlush = true;
有效。将 Flush()
方法添加到 Foo
并在适当的地方调用它也是如此,但我很感兴趣是否有任何方法可以不用。
您可以使用具有 Flush 方法的 StreamWriter。
对于您要完成的任务,还有另一种选择,您可以使用 File.AppendAllText 并且会起作用。这样就不会一直打开StreamWriter
class Foo
{
private static Foo instance;
private System.IO.StreamWriter os;
private Foo()
{
this.os = new System.IO.StreamWriter("D:/tmp/test.txt");
}
public static Foo Instance
{
get
{
if (instance == null)
instance = new Foo();
return instance;
}
}
public void Log(string s)
{
os.WriteLine(s);
os.Flush();
}
public void Log2(string s)
{
System.IO.File.AppendAllText(@"D:/tmp/test2.txt",s);
}
}
首先,使用单例本身就会产生问题,这不需要其他证明。在这里,它是对伪装的全局的清理。 StreamWriter
不会在程序结束时根据 the documentation、
You must call Close to ensure that all data is correctly written out to the underlying stream.
感谢@PeterDuniho 对“
private Foo()
{
this.os = System.IO.File.CreateText( "D:/tmp/test" );
System.AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => this.os.Close();
}
考虑到在析构函数中调用Close()
的问题,我不应该忽略到处写的"finalizers are not of much use anyway"。在这种情况下,由于垃圾回收没有使用特定的顺序,StreamWriter
对象已经被回收并且无法在其复活的僵尸状态下关闭。