Spreadsheetgear.IWorkbook / объект workbook. Как мне узнать длину рабочего блока? - PullRequest
0 голосов
/ 06 декабря 2009

Платформа разработки: .NET 2.0 Платформа: ASP.NET Spreadsheetgear: 2008 Язык: C #

Есть ли способ получить длину в байтах рабочей книги без ее копирования / сохранения в другом объекте?

Я просмотрел документацию и несколько попыток безуспешно.

Я сохраняю книгу с помощью метода SaveToStream, который записывает книгу непосредственно в Page.Response.OutputStream, который затем выгружается из браузера. Но так как тип этого объекта - Stream, этот абстрактный класс не реализует свойство Length, и приведение его к дочернему классу, такому как MemoryStream, возвратит нуль. В обоих случаях приложение выдаст исключение.

Мне нужно записать длину в байтах, чтобы зарегистрировать ее в целях анализа производительности в нашем приложении.

Моя цель состоит в том, чтобы избежать копирования этого потока в другой объект и, если возможно, с использованием только приведения ссылок, потому что нам нужно оптимизировать объем памяти модуля, который экспортирует в таблицы Excel в нашем приложении.

1 Ответ

1 голос
/ 06 декабря 2009

Если свойство 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);
...