Writing Console.Out to different output files
Iam trying to redirect Console.Out
to two text files using Console.SetOut
.
Console.SetOut(File.CreateText("c:\\del1.txt"));
Console.WriteLine(string1);
...
Console.SetOut(File.CreateText("c:\\del2.txt"));
Console.WriteLine(string2);
By this redirection two text files are created with out any data. This works fine if i comment out second redirection. How can i redirect output to differe开发者_运维技巧nt files using Console.SetOut
.
Edit1: Program terminates with out any errors, will this guarantee that all file streams are closed and flushed?
Edit2:
Thanks to every one who has replied to my question, i was able to find solution with out changing code and adding two extra lines to close the file stream.
Console.Out.Close();
Can any one explain why file streams are not closed and flushed after program terminates?
As Marc points out, you want different strings to different files. Why not just use File.AppendAllText
for every call?
Alternative you can do something like dynamic binding by employing the using
construct.
update:
A simple dynamic binding:
class DynamicConsole : TextWriter
{
readonly TextWriter orig;
readonly TextWriter output;
public DynamicConsole(string filename)
{
orig = Console.Out;
output = File.AppendText(filename);
Console.SetOut(output);
}
public override System.Text.Encoding Encoding
{
get { return output.Encoding; }
}
public override void Write(char value)
{
output.Write(value);
}
protected override void Dispose(bool disposing)
{
Console.SetOut(orig);
output.Dispose();
}
}
Usage (nested works too):
Console.WriteLine("Real 1");
using (new DynamicConsole("Foo.txt"))
{
Console.WriteLine("Moo");
using (new DynamicConsole("Bar.txt"))
{
Console.WriteLine("Ork");
}
Console.WriteLine("Bar");
}
Console.WriteLine("Real 2");
This will print to the Console
:
Real 1
Real 2
It will append to Foo.txt
:
Moo
Bar
It will append to Bar.txt
:
Ork
That is a very bizarre scenario - IMO you should just have two different TextWriter
, and write to them when you need to. Leave the console alone. If the caller wants to pipe stdout, let them worry about that via the command shell.
using(var file = File.CreateText(@"c:\del1.txt")) {
file.WriteLine(string1);
}
using(var file = File.CreateText(@"c:\del2.txt")) {
file.WriteLine(string2);
}
and if that means changing some existing code to pass in a TextWriter
, then that is purely a good thing.
using (TextWriter file1 = File.CreateText("c:\\del1.txt")) {
using (TextWriter file2 = File.CreateText("c:\\del2.txt")) {
Console.SetOut(file1);
Console.WriteLine("test1");
Console.SetOut(file2);
Console.WriteLine("test2");
}
}
Set AutoFlush property of each System.IO.StreamWriter returned by System.IO.File.CreateText to true.
Move to Tracing functionality, and add the ConsoleTraceListener as one of the listeners. Then add your text files using a TextWriterTraceListener.
Use trace switches to redirect to one listener or another.
More explanation can be found here http://msdn.microsoft.com/en-us/library/system.diagnostics.traceswitch.aspx.
EDIT: Modified so that you can do different strings to different files..
Could you not write a wrapper class that does this for you?
public class MyConsole
{
//private List<IO.StreamWriter> m_Outputs = new List<IO.StreamWriter>();
private Dictionary<String, IO.StreamWriter> m_Outputs = new Dictionary<String, IO.StreamWriter>();
public MyConsole() { }
public MyConsole(string _token, string _file)
{
AddOutput(_token, _file);
}
public void AddOutput(string _token, string _file)
{
IO.StreamWriter writer = new IO.StreamWriter(_file)
m_Outputs[_token] = writer;
}
public void WriteLine(string _token, string _data)
{
if(m_Outputs.ContainsKey(_token))
m_Outputs[_token].WriteLine(_data);
}
public void Close()
{
foreach(KeyValuePair<String, IO.StreamWriter> pair in m_Outputs)
pair.Value.Close();
}
} // eo class MyConsole
Usage:
MyConsole c = new MyConsole(); // or pass a file explicitly here
c.AddOutput("file1", "C:\\file1.txt");
c.AddOutput("file2", "C:\\file2.txt");
c.WriteLine("file1", "Test!");
c.WriteLine("file2", "Test2!");
Note this code is not tested and is written as-is, no warranty implied. :P
Can any one explain why file streams are not closed and flushed after program terminates?
The handles to the files would eventually be released when the resource is finally disposed of. By explicitly closing the file handles, you guarantee WHEN the release happens (rather than guaranteeing THAT the release happens - it would eventually happen if you left it up to the framework).
So always close your file handles explicitly so you know you have tied up a file for the shortest amount of time possible.
精彩评论