如何在 .NET 中将 StreamWriter 的源设置为多个?
How can I set StreamWriter's source as multiple in .NET?
我正在用 .NET 开发一些网络程序。
我想在我的输出 window 上看到整个文本流作为日志。
所以我试图搜索在 StreamWriter 上设置多个源的解决方案。
但我找不到。
我想要像下面这样的样式而不是扩展方法:
var sw = new StreamWriter(socketStream, traceStream)
或
var sw = new StreamWriter(socketStream);
sw.setSecondStream(traceStream);
制作分流器应该不难。对于没有 Seek 函数的只写流,它非常简单。
构造函数调用看起来像
var sw = new StreamWriter(new WriteStreamSplitter(socketStream, traceStream));
和 class(未经测试,只是一个模型)
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();
}
}
}
我认为你应该采取不同的方法。创建一个 class 并聚合一个 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);
}
}
这允许您附加附加功能。
无需使用您的代码创建 StreamWriter 的实例,您只需创建一个 MyStreamWriter:
var sw = new MyStreamWriter(socketStream);
我使用 Trace class 来记录消息,而不是将其写入另一个流。 log4net 等组件允许记录对跟踪(或调试)class 的所有调用,并将其路由到日志文件/SQL-服务器/其他。这样你就会有一个更灵活的解决方案。
作为替代方案,您可以自己实现 TraceListener,只需将所有输出添加到文本框即可。
谢谢你,亨克。好主意!
但我改变了一点。我只需要日志功能,所以我添加了日志概念。它基于您的拆分器想法。
可记录的流类
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");
}
我正在用 .NET 开发一些网络程序。 我想在我的输出 window 上看到整个文本流作为日志。 所以我试图搜索在 StreamWriter 上设置多个源的解决方案。 但我找不到。 我想要像下面这样的样式而不是扩展方法:
var sw = new StreamWriter(socketStream, traceStream)
或
var sw = new StreamWriter(socketStream);
sw.setSecondStream(traceStream);
制作分流器应该不难。对于没有 Seek 函数的只写流,它非常简单。
构造函数调用看起来像
var sw = new StreamWriter(new WriteStreamSplitter(socketStream, traceStream));
和 class(未经测试,只是一个模型)
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();
}
}
}
我认为你应该采取不同的方法。创建一个 class 并聚合一个 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);
}
}
这允许您附加附加功能。
无需使用您的代码创建 StreamWriter 的实例,您只需创建一个 MyStreamWriter:
var sw = new MyStreamWriter(socketStream);
我使用 Trace class 来记录消息,而不是将其写入另一个流。 log4net 等组件允许记录对跟踪(或调试)class 的所有调用,并将其路由到日志文件/SQL-服务器/其他。这样你就会有一个更灵活的解决方案。
作为替代方案,您可以自己实现 TraceListener,只需将所有输出添加到文本框即可。
谢谢你,亨克。好主意!
但我改变了一点。我只需要日志功能,所以我添加了日志概念。它基于您的拆分器想法。
可记录的流类
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");
}