如果未实现 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);