namespace BuildFlow.Workflow.Tests.Performance; /// 记录读取次数、总字节数和单次最大读取请求的只读测试流。 public sealed class TrackingReadStream(Stream inner) : Stream { /// 累计实际读取字节数。 public long BytesRead { get; private set; } /// 累计读取调用次数。 public int ReadCalls { get; private set; } /// 单次读取请求的最大缓冲区长度。 public int MaxRequestedReadSize { get; private set; } public override bool CanRead => inner.CanRead; public override bool CanSeek => inner.CanSeek; public override bool CanWrite => false; public override long Length => inner.Length; public override long Position { get => inner.Position; set => inner.Position = value; } public override void Flush() => inner.Flush(); public override int Read(byte[] buffer, int offset, int count) { RecordRequest(count); var read = inner.Read(buffer, offset, count); BytesRead += read; return read; } public override int Read(Span buffer) { RecordRequest(buffer.Length); var read = inner.Read(buffer); BytesRead += read; return read; } public override async ValueTask ReadAsync( Memory buffer, CancellationToken cancellationToken = default) { RecordRequest(buffer.Length); var read = await inner.ReadAsync(buffer, cancellationToken); BytesRead += read; return read; } public override async Task ReadAsync( byte[] buffer, int offset, int count, CancellationToken cancellationToken) { RecordRequest(count); var read = await inner.ReadAsync(buffer.AsMemory(offset, count), cancellationToken); BytesRead += read; return read; } public override long Seek(long offset, SeekOrigin origin) => inner.Seek(offset, origin); public override void SetLength(long value) => throw new NotSupportedException(); public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); protected override void Dispose(bool disposing) { if (disposing) { inner.Dispose(); } base.Dispose(disposing); } private void RecordRequest(int count) { ReadCalls++; MaxRequestedReadSize = Math.Max(MaxRequestedReadSize, count); } }