我目前正在编写一个缓存BaseStream.Position和BaseStream.Length属性的BinaryReader。这是我到目前为止所知道的:
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();
}
}我不想提供Length和Position属性,而是创建一个BaseStream属性,它允许我将Position和Length属性公开为FastBinaryReader.BaseStream.Position和FastBinaryReader.BaseStream.Length,这样我的现有代码就可以与原始的BinaryReader类保持兼容。
我该怎么做呢?
发布于 2011-10-20 00:16:27
我不会完全按照你这里的方式来做。
考虑一下,您需要公开一个Stream类型的属性(即BinaryReader.BaseStream )。所以你需要创建你自己的从Stream派生的类。这个类需要:
FastBinaryReader,以便它可以通过委托给FastBinaryReader成员来覆盖Stream.Length和Stream.Offset Stream (与在D12构造函数中传递的相同),以便将所有其他操作委托给该流(您可以使用这些D13,但您永远不知道哪个库方法将调用它们!)H214 F215你可以想象它看起来是什么样子:
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本身中:
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语句的结果,而不是缓存Length和Position的结果
发布于 2011-10-20 01:51:56
这里是最终的实现,如果有人感兴趣的话。将它作为Stream对象传递给BinaryReader,而不是通常的FileStream对象,在我的机器上,当读取1000字节块时,速度大约提高了45%。
请注意,长度参数只有在读取时才是准确的,因为长度是在开始时读取的,并且不会更改。如果您正在编写代码,它将不会随着基础流的长度更改而更新。
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();
}
}https://stackoverflow.com/questions/7824255
复制相似问题