开发平台:.NET 2.0 平台:ASP.NET Spreadsheetgear:2008 语言:C#
有没有办法检索工作簿的长度而不复制它/将其保存到另一个对象?
我查看了文档并进行了多次尝试但没有成功。
我正在使用SaveToStream方法保存工作簿,该方法将工作簿直接写入Page.Response.OutputStream,然后将其从浏览器中刷新。但由于此对象的类型是Stream,因此此抽象类不实现Length属性并将其强制转换为子类,如MemoryStream将返回null。在这两种情况下,应用程序都会抛出异常。
我需要捕获字节长度,以便在我们的应用程序中记录它以进行性能检查。
我的目的是避免将Stream复制到另一个对象,如果可能的话,只使用参考演员,因为我们需要优化导出到Excel应用程序中的Excel电子表格的模块的内存占用量。
答案 0 :(得分:1)
如果未实现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);