将控制台输出重定向到可读内存,而不是文件

本文关键字:文件 内存 输出 控制台 重定向 | 更新日期: 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和处理传入的数据