Length プロパティが実装されていない場合は、ストリーム全体を MemoryStream にコピーし、その長さを取得してから、メモリ ストリームからストリームを送信できます。
これの欠点は、長さを知る前にコピー全体が完了するまで待たなければならず、ストリーミングの側面が損なわれることです。代わりに、通過するバイトをカウントし、最後に要求できる現在の合計を保持する新しいストリームを実装できます。これを実装する方法は次のとおりです。
public class LengthLoggingStream : Stream
{
private Stream stream;
public long TotalBytesRead { get; private set; }
public long TotalBytesWritten { get; private set; }
public LengthLoggingStream(Stream stream)
{
this.stream = stream;
}
public override bool CanRead
{
get { return stream.CanRead; }
}
public override bool CanSeek
{
get { return stream.CanSeek; }
}
public override bool CanWrite
{
get { return stream.CanWrite; }
}
public override void Flush()
{
stream.Flush();
}
public override long Length
{
get { return stream.Length; }
}
public override long Position
{
get
{
return stream.Position;
}
set
{
stream.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
int bytesRead = stream.Read(buffer, offset, count);
if (bytesRead > 0)
TotalBytesRead += bytesRead;
return bytesRead;
}
public override long Seek(long offset, SeekOrigin origin)
{
return stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
TotalBytesWritten += count;
stream.Write(buffer, offset, count);
}
}
Response.OutputStream をこのクラスでラップし、フラッシュしてから、書き込まれたバイト数を確認できます。
LengthLoggingStream loggingStream = new LengthLoggingStream(Response.OutputStream);
workbook.SaveToStream(loggingStream, /*other parameters */);
log("Bytes written: " + loggingStream.TotalBytesWritten);