将控制台输出重定向到可读内存,而不是文件
本文关键字:文件 内存 输出 控制台 重定向 | 更新日期: 2023-09-27 18:15:54
我使用这段代码将控制台输出重定向到file,然后读取并显示它。我不想再使用文件了,因为控制台文件污染了我的文件夹。我如何在内存中做到这一点?我不想让任何文件污染系统。也许我在尝试一些奇怪的事情。我只想让1个线程读取同一个应用程序的控制台输出:
- <
- 1应用程序/gh>
- 多个线程写入控制台
- 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 { }
}
}
这似乎是我想要的。但我无法实现这一点。文件就像一个缓冲区。你从它的一端写信,从另一端读。我需要相同的内存
尝试:
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);
// ...
}
使用MemoryStream的问题是读位置随着写位置而前进。管道(先。pipe(命名空间)是作为临时缓冲区使用的更好选择,其中读位置需要独立于写位置前进。不可否认,这或多或少完全符合您的工作解决方案,尽管它消除了自己实现缓冲区的需要。
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);
}
}
我最终编写了一个派生流类,并用我自己的流替换了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
和处理传入的数据