首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提高BinaryReader的性能

提高BinaryReader的性能
EN

Stack Overflow用户
提问于 2011-10-19 23:56:48
回答 2查看 4.7K关注 0票数 3

我目前正在编写一个缓存BaseStream.PositionBaseStream.Length属性的BinaryReader。这是我到目前为止所知道的:

代码语言:javascript
复制
public class FastBinaryReader
{
    BinaryReader reader;

    public long Length { get; private set; }
    public long Position { get; private set; }

    public FastBinaryReader(Stream stream)
    {
        reader = new BinaryReader(stream);
        Length = stream.Length;
        Position = 0;
    }

    public void Seek(long newPosition)
    {
        reader.BaseStream.Position = newPosition;
        Position = newPosition;
    }

    public byte[] ReadBytes(int count)
    {
        if (Position + count >= Length)
            Position = Length;
        else
            Position += count;

        return reader.ReadBytes(count);
    }

    public void Close()
    {
        reader.Close();
    }
}

我不想提供LengthPosition属性,而是创建一个BaseStream属性,它允许我将PositionLength属性公开为FastBinaryReader.BaseStream.PositionFastBinaryReader.BaseStream.Length,这样我的现有代码就可以与原始的BinaryReader类保持兼容。

我该怎么做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-20 00:16:27

我不会完全按照你这里的方式来做。

考虑一下,您需要公开一个Stream类型的属性(即BinaryReader.BaseStream )。所以你需要创建你自己的从Stream派生的类。这个类需要:

  • 引用FastBinaryReader,以便它可以通过委托给FastBinaryReader成员来覆盖Stream.LengthStream.Offset
  • 引用Stream (与在D12构造函数中传递的相同),以便将所有其他操作委托给该流(您可以使用这些D13,但您永远不知道哪个库方法将调用它们!)H214 F215

你可以想象它看起来是什么样子:

代码语言:javascript
复制
private class StreamWrapper : Stream
{
    private readonly FastBinaryReader reader;

    private readonly Stream baseStream;

    public StreamWrapper(FastBinaryReader reader, Stream baseStream)
    {
        this.reader = reader;
        this.baseStream = baseStream;
    }
    public override long Length
    {
        get { return reader.Length; }
    }

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

    // Override all other Stream virtuals as well
}

这是可行的,但在我看来有点笨拙。逻辑上的延续是将缓存放在StreamWrapper中,而不是放在FastBinaryReader本身中:

代码语言:javascript
复制
private class StreamWrapper : Stream
{
    private readonly Stream baseStream;

    public StreamWrapper(Stream baseStream)
    {
        this.baseStream = baseStream;
    }

    public override long Length
    {
        get { /* caching implementation */ }
    }

    public override long Position
    {
        get { /* caching implementation */ }
        set { /* caching implementation */ }
    }

    // Override all other Stream virtuals as well
}

这将允许您透明地使用StreamWrapper并保持缓存行为。但它提出了一个问题:您使用的Stream是否如此愚蠢,以至于它不会自己缓存这些内容?

如果不是,那么您看到的性能提升可能是ReadBytes中的if语句的结果,而不是缓存LengthPosition的结果

票数 2
EN

Stack Overflow用户

发布于 2011-10-20 01:51:56

这里是最终的实现,如果有人感兴趣的话。将它作为Stream对象传递给BinaryReader,而不是通常的FileStream对象,在我的机器上,当读取1000字节块时,速度大约提高了45%。

请注意,长度参数只有在读取时才是准确的,因为长度是在开始时读取的,并且不会更改。如果您正在编写代码,它将不会随着基础流的长度更改而更新。

代码语言:javascript
复制
public class FastFileStream : FileStream
{
    private long _position;
    private long _length;

    public FastFileStream(string path, FileMode fileMode) : base(path, fileMode)
    {
        _position = base.Position;
        _length = base.Length;
    }

    public override long Length
    {
        get { return _length; }
    }

    public override long Position
    {
        get { return _position; }
        set
        {
            base.Position = value;
            _position = value;
        }
    }

    public override long Seek(long offset, SeekOrigin seekOrigin)
    {
        switch (seekOrigin)
        {
            case SeekOrigin.Begin:
                _position = offset;
                break;
            case SeekOrigin.Current:
                _position += offset;
                break;
            case SeekOrigin.End:
                _position = Length + offset;
                break;
        }
        return base.Seek(offset, seekOrigin);
    }

    public override int Read(byte[] array, int offset, int count)
    {
        _position += count;
        return base.Read(array, offset, count);
    }

    public override int ReadByte()
    {
        _position += 1;
        return base.ReadByte();
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7824255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档