Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对流中的读写进行计数_C#_.net - Fatal编程技术网

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对于读取,您必须先代理,然后递增-才能知道包装的流实际返回了多少个字符,但是:是的,那是