我使用此代码将控制台输出重定向到文件,然后读取并显示它。我想放弃使用文件,因为我用这些控制台文件污染了我的文件夹。我怎么能在记忆中这样做?我不希望任何文件污染系统。也许我在这里尝试一些奇怪的东西。 我只想要1个线程来读取同一个应用程序的控制台输出:
我的工作文件代码:
private StreamWriter currentOut = null;
private void RedirectConsole()
{
currentOut = new StreamWriter(new FileStream(filename,
FileMode.Create, FileAccess.Write, FileShare.Read));
currentOut.AutoFlush = true;
Console.SetOut(currentOut);
ThreadPool.QueueUserWorkItem(o => { Listen(); });
}
private void Listen()
{
StreamReader fileIn = new StreamReader(new FileStream(filename,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
while (true)
{
try
{
if (!fileIn.EndOfStream)
{
string a = fileIn.ReadLine();
MessageBox.Show(a);
}
Thread.Sleep(25);
}
catch { }
}
}
This似乎就是我想要的。但我无法实现(帮助?)。文件就像一个缓冲区。你从一端写到它并从另一端读。我需要内存相同。
答案 0 :(得分:1)
尝试:
private StreamWriter currentOut = null;
private MemoryStream ms = new MemoryStream();
private void RedirectConsole()
{
currentOut = new StreamWriter(ms);
currentOut.AutoFlush = true;
Console.SetOut(currentOut);
ThreadPool.QueueUserWorkItem(o => { Listen(); });
}
private void Listen()
{
StreamReader fileIn = new StreamReader(ms);
// ...
}
答案 1 :(得分:0)
我最终编写了一个派生流类,并用我自己的流替换了FileStream
。我应该避免这样做。但由于我找不到工作解决方案,这也是一个很好的做法。像这样:
public class MyStream: Stream
{
private byte[] internalBuffer = new byte[4096];
// ...
public override int Read(byte[] buffer, int offset, int count)
{
// used by StreamReader
}
public override void Write(byte[] buffer, int offset, int count)
{
// used by StreamWriter
}
}
override
所有其他内容,在扩展internalBuffer
和处理传递的数据时处理多线程。
答案 2 :(得分:0)
使用MemoryStream的问题在于读取位置随写入位置前进。管道(System.IO.Pipes命名空间)是用作临时缓冲区的更好选择,其中读取位置需要独立于写入位置而前进。不可否认,这或多或少与您的工作解决方案完全相同,但它不需要自己实现缓冲区。
class ConsoleRedirector : IDisposable
{
private TextWriter originalOut = Console.Out;
private AnonymousPipeServerStream consoleOutServerPipe;
private StreamWriter currentOut;
public ConsoleRedirector()
{
this.consoleOutServerPipe = new AnonymousPipeServerStream(PipeDirection.Out);
this.currentOut = new StreamWriter(this.consoleOutServerPipe);
this.currentOut.AutoFlush = true;
Console.SetOut(this.currentOut);
ThreadPool.QueueUserWorkItem(o => { this.Listen(); });
}
private void Listen()
{
AnonymousPipeClientStream consoleOutClientPipe = new AnonymousPipeClientStream(PipeDirection.In, this.consoleOutServerPipe.ClientSafePipeHandle);
using (StreamReader fileIn = new StreamReader(consoleOutClientPipe))
{
// ...
}
}
public void Dispose()
{
this.currentOut.Dispose();
Console.SetOut(this.originalOut);
}
}