如何在.NET中将StreamWriter的源设置为多个?

时间:2015-11-26 09:52:54

标签: c# .net sockets logging streamwriter

我正在开发.NET中的一些网络程序。 我想在输出窗口上看到整个文本流作为日志。 所以我试图在StreamWriter上搜索设置多个源的解决方案。 但我找不到。 我想要这样的风格,如下面的扩展方法:

var sw = new StreamWriter(socketStream, traceStream)

var sw = new StreamWriter(socketStream);
sw.setSecondStream(traceStream);

3 个答案:

答案 0 :(得分:2)

制作分流器应该不会那么困难。对于没有Seek功能的只写流,它非常简单。

构造函数调用看起来像

var sw = new StreamWriter(new WriteStreamSplitter(socketStream, traceStream));

和班级(未经测试,只是模拟)

class WriteStreamSplitter : Stream
{
    public WriteStreamSplitter(Stream a, Stream b)
    {
        _streamA = a;
        _streamB = b;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        _streamA.Write(buffer, offset, count);
        _streamB.Write(buffer, offset, count);
    }

    public override bool CanWrite { get { return true; } }
    public override bool CanRead  { get { return false; } }

    // trivial overloads of all other abstract members, 
    // they are allowed to throw NotImplemented


    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (disposing)
        {
            // Maybe it's best to do nothing here but a StreamWriter 
            // assumes 'ownership' of the wrapped stream, 
            // so if we want to continue that pattern:

            // the guidelines say these shouldn't throw
            _streamA.Dispose();
            _streamB.Dispose();
        }
    }
}

答案 1 :(得分:2)

我认为你应该采取不同的方法。创建一个类并聚合StreamWriter。然后使用MyStreamWriter写入流而不是直接使用StreamWriter:

class MyStreamWriter
{
   private StreamWriter sw;

   // Constructor
   public MyStreamWriter(Stream socketStream)
   {
      sw = new StreamWriter(socketStream);
   }

   // Example function
   public void WriteLine(string myText)
   {
     Trace.WriteLine(myText);
     sw.WriteLine(myText);
   }
}

这允许您附加其他功能。

您只需创建 MyStreamWriter ,而不是使用代码创建StreamWriter实例:

var sw = new MyStreamWriter(socketStream);

我使用Trace类来记录消息,而不是将其写入另一个流。像log4net这样的组件允许记录对Trace(或Debug)类的所有调用,并将其路由到日志文件/ SQL-Server /等等。这样您就可以获得更灵活的解决方案。

作为替代方案,您可以自己实现TraceListener,这可以简单地将所有输出添加到TextBox。

答案 2 :(得分:0)

谢谢你,Henk。好主意!

但我改变了一点。我只需要记录功能,所以我添加了日志概念。它基于你的分裂者的想法。

可记录的流类

public class LoggableStream : Stream
{
    private Stream _stream;
    private Encoding _textEncoding;



    public LoggableStream(Stream stream, Encoding textEncoding)
    {
        _stream = stream;
        _textEncoding = textEncoding;
    }

    public override bool CanRead
    {
        get
        {
            return _stream.CanRead;
        }
    }

    public override bool CanSeek
    {
        get
        {
            return _stream.CanSeek;
        }
    }

    public override bool CanWrite
    {
        get
        {
            return _stream.CanWrite;
        }
    }

    public override long Length
    {
        get
        {
            return _stream.Length;
        }
    }

    public override long Position
    {
        get
        {
            return _stream.Position;
        }
        set
        {
            _stream.Position = Position;
        }
    }

    public override void Flush()
    {
        _stream.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        var result = _stream.Read(buffer, offset, count);

        try
        {
            var log = this._textEncoding.GetString(buffer, offset, count);
            Trace.TraceInformation("READ : " + log);
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }

        return result;
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        var result = _stream.Seek(offset, origin);
        return result;
    }

    public override void SetLength(long value)
    {
        _stream.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        _stream.Write(buffer, offset, count);

        try
        {
            var log = this._textEncoding.GetString(buffer, offset, count);
            Trace.TraceInformation("WRIT : " + log);
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }
    }
}

的使用

using (var netStream = _controlClient.GetStream())
using (var sr = new StreamReader(new LoggableStream(netStream, Encoding.UTF8)))
using (var sw = new StreamWriter(new LoggableStream(netStream, Encoding.UTF8)))
{
    var readLine = sr.ReadLine();
    sw.WriteLine("hello");
}