public class ConstrainedStream : Stream
private readonly Stream _baseStream;
public long ConstrainedLength { get; set; }
public override bool CanRead => _baseStream.CanRead;
public override bool CanSeek => _baseStream.CanSeek;
public override bool CanWrite => false;
public override long Length => Math.Min(ConstrainedLength, _baseStream.Length);
public override long Position
get => _baseStream.Position;
set => _baseStream.Position = value;
public ConstrainedStream(Stream baseStream)
_baseStream = baseStream;
public override void Flush() => _baseStream.Flush();
public override int Read(byte[] buffer, int offset, int count)
long maxLength = Math.Min(Length, ConstrainedLength) - Position;
return _baseStream.Read(buffer, offset, (int)Math.Min(count, maxLength));
public override long Seek(long offset, SeekOrigin origin)
return _baseStream.Seek(offset, origin);
public override void SetLength(long value) => _baseStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
public static void Main()
<data><data><data><data><data><data>...
<data><data><data><data><data><data>...
byte[] bytes = Encoding.ASCII.GetBytes(content);
var file = new MemoryStream(bytes);
var constrainedStream = new ConstrainedStream(file) { ConstrainedLength = 1 };
var reader = new StreamReader(constrainedStream);
constrainedStream.ConstrainedLength++;
if (constrainedStream.ConstrainedLength > file.Length)
reader.DiscardBufferedData();
file.Position = startPosition;
string? line = reader.ReadLine();
if (line != null && !reader.EndOfStream)
startPosition = file.Position - 1;
if (reader.ReadLine() == "")
Console.WriteLine("Body:");
Console.WriteLine(new StreamReader(file).ReadToEnd());