克隆 BinaryReader 的读取字节

Clone read bytes of BinaryReader

我正在使用 BinaryReader 来解析某些数据。我想将读取的字节复制到辅助流。我该怎么做?

如果我从 BinaryReader 派生(实际上我需要这样做是出于不同的原因),我需要覆盖哪些方法才能获得正确的行为?

BinaryReader 不是真正的 Stream... 它更像是另一个流的叠加。你可以:

using (var yourStream = /* ... */)
using (var br = new BinaryReader(yourStream))
{
    using (var ms = new MemoryStream())
    {
        // Important the true, so that the ms remains open!
        using (var bw = new BinaryWriter(ms, Encoding.UTF8, true))
        {
            var readed = br.ReadInt32();
            bw.Write(readed); 
            // All the basic types are supported by various overlaods
        }

        // Here you have your ms... If you want to reread it:
        ms.Position = 0;

        using (var br2 = new BinaryReader(ms, Encoding.UTF8, true))
        {
            // Reread it
        }

        // Or copy it to another stream, or do whatever you want
    }
}

如果您只是想在阅读时将一个流复制到另一个流,您可以使用类似的东西:

public class CopyStream : Stream
{
    // This is the stream you want to read your data from
    public Stream ReadStream { get; set; }

    // This is the "logger" stream, where a copy of read data will be put
    public Stream LogStream { get; set; }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int res = ReadStream.Read(buffer, offset, count);

        if (LogStream != null)
        {
            if (res > 0)
            {
                LogStream.Write(buffer, offset, res);
            }
        }

        return res;
    }

    public override int ReadByte()
    {
        int res = ReadStream.ReadByte();

        if (LogStream != null)
        {
            if (res >= 0)
            {
                LogStream.WriteByte((byte)res);
            }
        }

        return res;
    }

    public override bool CanSeek
    {
        get { return false; }
    }
}

您需要实施/throw NotImplementedException() 许多其他方法,因为 Stream 是一个 abstract class。右键单击 StreamImplement Abstract Class 将加快速度。

基本用法是:

var cs = new CopyStream
    {
        ReadStream = yourStream,
        LogStream = whereyouwanttoWriteStream,
    };

using (var br = new BinaryReader(CopyStream, Encoding.UTF8, true))
{
    // Here you can read normally from the BinaryReader.
    // Everything you read will be copied to LogStream 
}

请注意,子类化 BinaryReader 非常复杂,因为每个方法以不同的方式加载数据,因此没有一个 "point of interception".

流应该被封装,而不是被覆盖:

public class DuploStream : Stream
{
    private readonly Stream _underlyingStream;
    private readonly Stream _copyStream;

    public DuploStream(Stream underlyingStream, Stream copyStream)
    {
        _underlyingStream = underlyingStream;
        _copyStream = copyStream;
    }

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

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

    public override long Length { get { throw new NotSupportedException(); } }
    public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } }

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

        _copyStream.Write(buffer, offset, bytesRead);

        return bytesRead;
    }

    public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); }
    public override void SetLength(long value) { throw new NotSupportedException(); }
    public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); }
}

然后,不是在底层流之上创建 BinaryReader,而是在 DuploStream 之上构建它,传递底层流和复制流。