Spreadsheetgear.IWorkbook / workbook对象。如何检索工作簿的长度?

时间:2009-12-06 02:18:26

标签: c# stream spreadsheetgear

开发平台:.NET 2.0 平台:ASP.NET Spreadsheetgear:2008 语言:C#

有没有办法检索工作簿的长度而不复制它/将其保存到另一个对象?

我查看了文档并进行了多次尝试但没有成功。

我正在使用SaveToStream方法保存工作簿,该方法将工作簿直接写入Page.Response.OutputStream,然后将其从浏览器中刷新。但由于此对象的类型是Stream,因此此抽象类不实现Length属性并将其强制转换为子类,如MemoryStream将返回null。在这两种情况下,应用程序都会抛出异常。

我需要捕获字节长度,以便在我们的应用程序中记录它以进行性能检查。

我的目的是避免将Stream复制到另一个对象,如果可能的话,只使用参考演员,因为我们需要优化导出到Excel应用程序中的Excel电子表格的模块的内存占用量。

1 个答案:

答案 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);