Копировать между двумя потоками в .net 2.0 - PullRequest
5 голосов
/ 15 сентября 2011

Я использовал следующий код для сжатия данных в .Net 4.0:

public static byte[] CompressData(byte[] data_toCompress)
{

    using (MemoryStream outFile = new MemoryStream())
    {
        using (MemoryStream inFile = new MemoryStream(data_toCompress))
        using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
        {
            inFile.CopyTo(Compress);

        }
        return outFile.ToArray();
    }

}

Однако в .Net 2.0 метод Stream.CopyTo недоступен.Итак, я попытался сделать замену:

public static byte[] CompressData(byte[] data_toCompress)
{

    using (MemoryStream outFile = new MemoryStream())
    {
        using (MemoryStream inFile = new MemoryStream(data_toCompress))
        using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
        {
            //inFile.CopyTo(Compress);
            Compress.Write(inFile.GetBuffer(), (int)inFile.Position, (int)(inFile.Length - inFile.Position));
        }
        return outFile.ToArray();
    }

}

Сжатие завершается неудачно, однако, при использовании вышеуказанной попытки - я получаю сообщение об ошибке:

Внутренний буфер MemoryStream не доступен.

Может ли кто-нибудь предложить какую-либо помощь по этому вопросу?Я действительно не уверен, что еще здесь делать.

Спасибо, Эван

Ответы [ 7 ]

7 голосов
/ 15 сентября 2011

Это код из метода .Net 4.0 Stream.CopyTo (bufferSize равен 4096):

byte[] buffer = new byte[bufferSize];
int count;
while ((count = this.Read(buffer, 0, buffer.Length)) != 0)
    destination.Write(buffer, 0, count);
3 голосов
/ 15 сентября 2011

Поскольку у вас уже есть доступ к массиву, почему бы вам не сделать это:

using (MemoryStream outFile = new MemoryStream())
{
    using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress))
    {
        Compress.Write(data_toCompress, 0, data_toCompress.Length);
    }
    return outFile.ToArray();
}

Скорее всего, в примере кода, который вы используете inFile.GetBuffer(), возникнет исключение, так как вы не используете правильный конструктор - не все экземпляры MemoryStream позволяют вам получить доступ к внутреннему буферу - вы должны найти это в документации:

Инициализирует новый экземпляр MemoryStreamкласс, основанный на указанной области байтового массива, со свойством CanWrite, установленным как указано, и возможностью вызова GetBuffer, установленным как указано .

Это должно работать - но этов предложенном решении все равно не нужно:

using (MemoryStream inFile = new MemoryStream(data_toCompress, 
                                              0, 
                                              data_toCompress.Length, 
                                              false, 
                                              true))
0 голосов
/ 06 сентября 2017

Пакет NuGet с открытым исходным кодом Stream.CopyTo реализует Stream.CopyTo для всех версий .NET Framework.

Доступно в GitHub и через NuGet (Install-Package Stream.CopyTo)

0 голосов
/ 15 сентября 2011

Вы должны вручную читать и писать между этими двумя потоками:

    private static void CopyStream(Stream from, Stream to)
    {
        int bufSize = 1024, count;
        byte[] buffer = new byte[bufSize];
        count = from.Read(buffer, 0, bufSize);
        while (count > 0)
        {
            to.Write(buffer, 0, count);
            count = from.Read(buffer, 0, bufSize);
        }
    }
0 голосов
/ 15 сентября 2011

попробуйте заменить строку:

Compress.Write(inFile.GetBuffer(), (int)inFile.Position, (int)(inFile.Length - inFile.Position));

с:

Compress.Write(data_toCompress, 0, data_toCompress.Length);

Вы можете полностью избавиться от этой строки:

using (MemoryStream inFile = new MemoryStream(data_toCompress))

Редактировать: найти пример здесь: Почему сжатие небольшого файла с помощью gzip / deflate приводит к множеству конечных нулей?

0 голосов
/ 15 сентября 2011

Можно попробовать

infile.WriteTo(Compress);
0 голосов
/ 15 сентября 2011

Почему вы создаете поток памяти с массивом, а затем пытаетесь извлечь массив из потока памяти?

Вы можете просто сделать Compress.Write(data_toCompress, 0, data_toCompress.Length);

Если вам нужнозаменив функциональность CopyTo, вы можете создать буферный массив некоторой длины, прочитать данные из исходного потока и записать эти данные в целевой поток.

...