C# 对流中的读写进行计数
计算流写入和读取多少字节的正确方法是什么?C# 对流中的读写进行计数,c#,.net,C#,.net,计算流写入和读取多少字节的正确方法是什么? 从流和重载方法派生很简单。 问题是任何Read**方法都可以调用其他Read**方法,然后我可能会数到两次。 有没有合适的解决办法 假设我为流做包装,我应该在哪里增加读写计数 public class CountStream : Stream { private readonly Stream _stream; protected CountStream (Stream stream) => _s
从流和重载方法派生很简单。
问题是任何Read**方法都可以调用其他Read**方法,然后我可能会数到两次。
有没有合适的解决办法 假设我为流做包装,我应该在哪里增加读写计数
public class CountStream : Stream
{
private readonly Stream _stream;
protected CountStream (Stream stream) => _stream = stream;
public override object InitializeLifetimeService() => _stream.InitializeLifetimeService();
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) => _stream.BeginRead(buffer, offset, count, callback, state);
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) => _stream.BeginWrite(buffer, offset, count, callback, state);
public override void Close()
{
_stream.Close();
}
public override int EndRead(IAsyncResult asyncResult) => _stream.EndRead(asyncResult);
public override void EndWrite(IAsyncResult asyncResult)
{
_stream.EndWrite(asyncResult);
}
public override void Flush()
{
_stream.Flush();
}
public override Task FlushAsync(CancellationToken cancellationToken) => _stream.FlushAsync(cancellationToken);
public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count);
public override int Read(Span<byte> buffer) => _stream.Read(buffer);
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => _stream.ReadAsync(buffer, offset, count, cancellationToken);
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = new CancellationToken()) => _stream.ReadAsync(buffer, cancellationToken);
public override int ReadByte() => _stream.ReadByte();
public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin);
public override void SetLength(long value)
{
_stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
}
public override void Write(ReadOnlySpan<byte> buffer)
{
_stream.Write(buffer);
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => _stream.WriteAsync(buffer, offset, count, cancellationToken);
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = new CancellationToken()) => _stream.WriteAsync(buffer, cancellationToken);
public override void WriteByte(byte value)
{
_stream.WriteByte(value);
}
public override bool CanRead => _stream.CanRead;
public override bool CanSeek => _stream.CanSeek;
public override bool CanTimeout => _stream.CanTimeout;
public override bool CanWrite => _stream.CanWrite;
public override long Length => _stream.Length;
public override long Position
{
get => _stream.Position;
set => _stream.Position = value;
}
public override int ReadTimeout
{
get => _stream.ReadTimeout;
set => _stream.ReadTimeout = value;
}
public override int WriteTimeout
{
get => _stream.WriteTimeout;
set => _stream.WriteTimeout = value;
}
}
公共类CountStream:Stream
{
私有只读流_流;
受保护的CountStream(Stream-Stream)=>\u Stream=Stream;
公共重写对象InitializeLifetimeService()=>_stream.InitializeLifetimeService();
公共重写IAsyncResult BeginRead(字节[]缓冲区,整数偏移量,整数计数,异步回调,对象?状态)=>\u stream.BeginRead(缓冲区,偏移量,计数,回调,状态);
公共重写IAsyncResult BeginWrite(字节[]缓冲区,整数偏移量,整数计数,异步回调,对象?状态)=>\u stream.BeginWrite(缓冲区,偏移量,计数,回调,状态);
公共覆盖无效关闭()
{
_stream.Close();
}
公共覆盖int-EndRead(IAsyncResult asyncResult)=>\u stream.EndRead(asyncResult);
公共重写void EndWrite(IAsyncResult asyncResult)
{
_EndWrite(异步结果);
}
公共覆盖无效刷新()
{
_stream.Flush();
}
公共覆盖任务FlushAsync(CancellationToken CancellationToken)=>\u stream.FlushAsync(CancellationToken);
公共覆盖整型读取(字节[]缓冲区,整型偏移量,整型计数)=>\u stream.Read(缓冲区,偏移量,计数);
公共覆盖整型读取(Span buffer)=>\u stream.Read(buffer);
公共重写任务ReadAsync(字节[]缓冲区,int偏移量,int计数,CancellationToken CancellationToken)=>\u stream.ReadAsync(缓冲区,偏移量,计数,CancellationToken);
公共重写值Task ReadAsync(内存缓冲区,CancellationToken CancellationToken=new CancellationToken())=>\u stream.ReadAsync(缓冲区,CancellationToken);
公共覆盖int ReadByte()=>_stream.ReadByte();
公共覆盖长寻道(长偏移,SeekOrigin原点)=>\u stream.Seek(偏移,原点);
公共覆盖无效设置长度(长值)
{
_stream.SetLength(值);
}
公共重写无效写入(字节[]缓冲区、整数偏移量、整数计数)
{
_写入(缓冲区、偏移量、计数);
}
公共重写无效写入(ReadOnlySpan缓冲区)
{
_流写入(缓冲区);
}
公共覆盖任务WriteAsync(字节[]缓冲区,整数偏移量,整数计数,取消令牌取消令牌)=>\u stream.WriteAsync(缓冲区,偏移量,计数,取消令牌);
public override ValueTask WriteAsync(只读内存缓冲区,CancellationToken CancellationToken=new CancellationToken())=>\u stream.WriteAsync(缓冲区,CancellationToken);
公共重写无效写字节(字节值)
{
_stream.WriteByte(值);
}
public override bool CanRead=>\u stream.CanRead;
public override bool CanSeek=>\u stream.CanSeek;
public override bool CanTimeout=>\u stream.CanTimeout;
public override bool CanWrite=>\u stream.CanWrite;
公共覆盖长长度=>\u stream.Length;
公众优先多头仓位
{
get=>\u stream.Position;
set=>\u stream.Position=值;
}
公共覆盖int读取超时
{
get=>\u stream.ReadTimeout;
set=>\u stream.ReadTimeout=value;
}
公共覆盖int WriteTimeout
{
get=>\u stream.WriteTimeout;
set=>\u stream.WriteTimeout=value;
}
}
只需将流重载嵌入实际的流对象即可。只要您自己的类中的函数不调用这些其他函数,如果您将所有调用传递给流对象上不计数的实际函数,则任何函数都不会计数两次。显示您的简单派生类以及Read如何调用另一个Read方法。您只需在所有其他方法调用的一个方法中保持计数。请使用BinaryReader。其他流使用字符(一个或两个字节),根据字符的大小,您将无法获得正确的字节计数。@jdweng不,流不会神奇地从字节切换到字符。像往常一样,你有点道理,但完全没有抓住。是的,有多字节编码,但如果您使用StreamReader并且仍然要计算字节数,这很重要。这里的OP是指一个不处理字符的流。@nyrguds对于读取,您必须先代理,然后递增-才能知道包装的流实际返回了多少个字符,但是:是的,那是