Зависимость от машины GZipStream

Я столкнулся с каким-то странным поведением GZipStream, зависящим от машины/ОС, в .NET 4.0. Это соответствующий код:

public static string Compress(string input) {
    using(var ms = new MemoryStream(Encoding.UTF8.GetBytes(input)))
    using(var os = new MemoryStream()) {
        using(var gz = new GZipStream(os,CompressionMode.Compress,true)) {
            ms.CopyTo(gz);
        }
        return string.Join("",os.ToArray().Select(b=>b.ToString("X2")));
    }
}

Запуск Compress("freek") дает мне

1F8B08000000000004004B2B4A4DCD06001E33909D05000000

на виндовс 7 и

1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22CEEB3C7FFBFF040000FFFF1E33909D05000000

на Windows Server 2008R2. Оба 64-битные. Я ожидаю, что результаты будут такими же.

Обе машины дают правильный результат, когда я распаковываю любой результат. Я уже выяснил, что на W7 ms.Length == 25, а на W2K8R2 ms.Length== 128, но не знаю почему.

Что происходит?


person Freek    schedule 21.03.2012    source источник
comment
С таким же успехом это может быть связано с MemoryStream. Пробовали без gzip?   -  person Henk Holterman    schedule 21.03.2012
comment
@Хенк, почему ты так думаешь? Заполняет ли MemoryStream остальные 123 байта на W2K8R2?   -  person Freek    schedule 21.03.2012
comment
Вы проверили в диспетчере задач, показывают ли обе машины это как 64-битный процесс или нет? Как у вас с настройками сборки?   -  person weismat    schedule 21.03.2012
comment
128 байт выглядит как размер блока для потока. Сжатие, скорее всего, будет использовать 128 бит   -  person Henk Holterman    schedule 21.03.2012
comment
Сжатие без потерь гарантирует восстановление того же результата после цикла сжатия-распаковки, но я не вижу причин ожидать, что сжатая форма всегда будет идентичной. Почему вы ожидаете, что ответы будут идентичными?   -  person J D    schedule 13.07.2012


Ответы (5)


Было объявлено, что .NET 4.5 Beta включает улучшения сжатия zip для уменьшения размера:

Начиная с .NET Framework 4.5 RC, класс DeflateStream использует для сжатия библиотеку zlib. В результате он обеспечивает лучший алгоритм сжатия и, в большинстве случаев, сжатый файл меньшего размера, чем в более ранних версиях .NET Framework.

Возможно, у вас установлен .Net 4.5+ на машине с Win7?

person Robert Levy    schedule 21.03.2012
comment
Это немного поразило нас здесь, в Stack Overflow, из-за запуска смешанного уровня 4.0 / 4.5 и сжатия содержимого перед его помещением в (что должно быть) уникальные наборы в Redis для кэширования. Если вы полагаетесь на один и тот же результат сжатия (например, для удаления элемента из набора), остерегайтесь запуска смешанной среды серверов 4.0 и 4.5. - person Nick Craver; 13.07.2012
comment
Здорово! Теперь я знаю, как объяснить на собеседовании с клиентом, почему моя программа не работает! - person VMAtm; 13.06.2013

Кажется, есть изменения в алгоритм, используемый DeflateStream в .NET 4.5:

Начиная с бета-версии .NET Framework 4.5 класс DeflateStream использует для сжатия библиотеку zlib. В результате он обеспечивает лучший алгоритм сжатия и, в большинстве случаев, сжатый файл меньшего размера, чем в более ранних версиях .NET Framework.

Поскольку у меня была установлена ​​​​4.5, это вызывало проблему.

person Freek    schedule 21.03.2012
comment
Я бы не считал это кардинальным изменением. Это просто улучшение производительности. У приложений не должно быть никаких ожиданий от этого API, кроме того, что он действителен в соответствии со спецификацией gzip. - person Robert Levy; 21.03.2012
comment
Это критическое изменение, но оно хуже, чем критические изменения в предыдущих выпусках. .NET 4.5 заменяет .NET 4.0, а это означает, что установка приложения на тот же компьютер, на котором используется .NET 4.5, может нарушить работу уже установленного приложения на том же компьютере, на котором использовалась .NET 4.0, но начнется использование .NET 4.5. - person zumalifeguard; 20.05.2013

В отличие от Абеля ответ, я получаю результат

1F8B08000000000004004B2B4A4DCD06001E33909D05000000

на моей Windows 7 x64 Ultimate SP1. Возможно, у вас нет обновления .NET Framework на одной из коробок? Версия моей mscorlib.dll — 4.0.30319.17379.

ETA: если я переориентируюсь на .NET 2 (и заменю конструкции, специфичные для .NET 4, на их эквиваленты для .NET 2), я получу результат

1F8B0800000000000400EDBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22CEEB3C7FFBFF001E33909D05000000

на той же машине/ОС.

person Jesse C. Slicer    schedule 21.03.2012
comment
Я подозреваю, что это из-за обновления SP1. Я тестирую это сейчас. - person Freek; 21.03.2012
comment
На самом деле, я делаю, на этой коробке. Я прочитал комментарий, который вы сделали относительно: повышенная сдуваемость в 4.5, и это попало бы в самую точку. Хорошая находка! - person Jesse C. Slicer; 21.03.2012

Я запустил ваш код на своей 64-битной машине с Windows 7 и получил следующее, что соответствует вашему Win2k8SP2:

1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F229ED579FEF6FF090000FFFF1A1C515C05000000

По сути, я думаю, что результат связан с длиной слова машины. То есть ваша машина с Windows-7, возможно, 32-битная?

ПРИМЕЧАНИЕ. Я написал небольшую распаковку для ваших строк, и я должен подтвердить, что они действительно хорошо распаковываются. Я запускал свою версию как в 32-битной, так и в 64-битной версии, и результат был одинаковым. Остается только возможная разница: разные среды выполнения?

РЕДАКТИРОВАТЬ:

разное время выполнения?

По-видимому, как Хенк Холтерман предложил ниже и Роберт Леви формализован в его ответе, здесь действительно был неочевидный случай .

person Abel    schedule 21.03.2012
comment
Оба 64-битные, забыл упомянуть. - person Freek; 21.03.2012
comment
Какую Visual Studio вы используете? - person Freek; 21.03.2012
comment
Я получаю тот же результат, что и Авель. Мы уверены, что версия VS такая же? - person user7116; 21.03.2012
comment
@ Хенк, похоже, проблема в этом, сейчас проверяю. Из MSDN: начиная с бета-версии .NET Framework 4.5 класс DeflateStream использует для сжатия библиотеку zlib. В результате он обеспечивает лучший алгоритм сжатия и, в большинстве случаев, сжатый файл меньшего размера, чем в более ранних версиях .NET Framework. - person Freek; 21.03.2012

Я подозреваю, что одна из операционных систем 32-битная, а другая 64-битная.

person daryal    schedule 21.03.2012