0

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

有没有办法在不复制/保存到另一个对象的情况下检索工作簿的长度(以字节为单位)?

我浏览了文档并进行了几次尝试,但均未成功。

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

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

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

4

1 回答 1

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);
于 2009-12-06T02:47:21.833 回答