【发布时间】:2021-07-10 10:36:21
【问题描述】:
有没有办法向后读取流?流是可搜索的。
【问题讨论】:
有没有办法向后读取流?流是可搜索的。
【问题讨论】:
您可以通过执行以下操作来反转流:
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()
{
}
}
【讨论】: