【问题标题】:Read a stream in reverse [duplicate]反向读取流[重复]
【发布时间】:2021-07-10 10:36:21
【问题描述】:

有没有办法向后读取流?流是可搜索的。

【问题讨论】:

    标签: c# stream reverse


    【解决方案1】:

    您可以通过执行以下操作来反转流:

    var reversedStream = new ReverseStream(stream);
    

    要反转文件:

    using (var inputFile = File.OpenRead("file.dat"))
    using (var inputFileReversed = new ReverseStream(inputFile))
    using (var outputFile = File.Open("file.dat.reversed", FileMode.Create, FileAccess.Write))
    {
        inputFileReversed.CopyTo(outputFile);
    }
    

    其中使用ReverseStream 类:

    public class ReverseStream : Stream
    {
        readonly Stream stream;
        public ReverseStream(Stream stream)
        {
            if (!stream.CanSeek) throw new Exception("Stream cannot seek");
    
            stream.Seek(stream.Position, SeekOrigin.End);
            this.stream = stream;
        }
    
        public override bool CanRead => true;
    
        public override bool CanSeek => true;
    
        public override bool CanWrite => false;
    
        public override long Length => stream.Length;
    
        public override long Position
        {
            get
            {
                var position = stream.Length - stream.Position;
                return position;
            }
    
            set
            {
                stream.Position = stream.Length - value;
            }
        }
    
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (stream.Position == 0) return 0;
    
            var startReadFrom = stream.Position - count;
            if (startReadFrom < 0)
            {
                count += (int)startReadFrom;
                startReadFrom = 0;
            }
    
            stream.Seek(startReadFrom, SeekOrigin.Begin);
            var bytesRead = stream.Read(buffer, offset, count);
            stream.Seek(startReadFrom, SeekOrigin.Begin);
    
            Array.Reverse(buffer, offset, bytesRead);
    
            return bytesRead;
        }
    
        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
                case SeekOrigin.Begin:
                    stream.Seek(offset, SeekOrigin.End);
                    break;
    
                case SeekOrigin.End:
                    stream.Seek(offset, SeekOrigin.Begin);
                    break;
    
                case SeekOrigin.Current:
                    stream.Seek(-offset, SeekOrigin.Current);
                    break;
            }
    
            return Position;
        }
    
        public override void SetLength(long value)
        {
        }
    
        public override void Write(byte[] buffer, int offset, int count)
        {
        }
        public override void Flush()
        {
        }
    }
    

    【讨论】:

    • 在某些边缘情况下,可以寻找流并且没有固定(提前)长度。这个类不处理它们(实际上它无法处理)。例如:一些无穷无尽的流。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    相关资源
    最近更新 更多