0

開発プラットフォーム: .NET 2.0 プラットフォーム: ASP.NET Spreadsheetgear: 2008 言語: C#

ワークブックの長さを別のオブジェクトにコピー/保存せずにバイト単位で取得する方法はありますか?

私はドキュメントといくつかの試みを経験しましたが、成功しませんでした。

ワークブックを Page.Response.OutputStream に直接書き込む SaveToStream メソッドを使用してワークブックを保存しています。このメソッドは、ブラウザからフラッシュされます。ただし、このオブジェクトの型は Stream であるため、この抽象クラスは Length プロパティを実装せず、これを MemoryStream のような子クラスにキャストすると null が返されます。どちらの場合も、アプリは例外をスローします。

アプリケーションでパフォーマンス レビューを目的としてログに記録するには、長さをバイト単位で取得する必要があります。

私の目的は、その Stream を別のオブジェクトにコピーすることを避け、可能であれば参照キャストのみを使用することです。これは、アウト アプリケーションで 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 に答える