DeflateStream и GZipStream записывают заголовки и закрывающие части для пустой нагрузки

DeflateStream и GZipStream теперь всегда записывают заголовки и нижние колонтитулы формата в выходной поток, даже если данные не записываются. Это гарантирует, что выходные данные являются допустимым сжатым потоком в соответствии со спецификациями Deflate и GZip.

Представленная версия

.NET 11( предварительная версия 1)

Предыдущее поведение

Ранее DeflateStream и GZipStream не производили никаких выходных данных, если данные не были записаны в поток. Это привело к пустому потоку выходных данных при сжатие пустых входных данных.

using var output = new MemoryStream();
using (var deflate = new DeflateStream(output, CompressionMode.Compress))
{
    // No data written.
}
Console.WriteLine(output.Length); // 0

Новое поведение

Начиная с версии .NET 11, DeflateStream и GZipStream всегда записывают соответствующие верхние и нижние колонтитулы в выходной поток, даже если данные не записываются. Это гарантирует, что выходные данные содержат допустимые сжатые данные в соответствии со спецификациями формата.

using var output = new MemoryStream();
using (var deflate = new DeflateStream(output, CompressionMode.Compress))
{
    // No data written.
}
Console.WriteLine(output.Length); // 2 (for Deflate) or 20 (for GZip).

Тип разрушающего изменения

Это изменение поведения.

Причина изменения

Форматы сжатия Deflate и GZip включают разделители для начала и окончания сжатых данных. Правильный способ сжатия пустой полезной нагрузки в этих форматах включает только те разделители. Некоторые инструменты не корректно реагируют на пустое содержимое и всегда ожидают, что сжатый контент будет содержать, по крайней мере, соответствующий заголовок и нижний колонтитул. Это изменение гарантирует совместимость с такими инструментами и правильно форматирует сжатые потоки в соответствии с спецификациями.

Если необходимо предыдущее поведение, управляйте пустым содержимым особым образом, чтобы не сжимать его через DeflateStream или GZipStream.

byte[] dataToCompress = GetData();

if (dataToCompress.Length == 0)
{
    // Don't compress empty data.
    return Array.Empty<byte>();
}

using var output = new MemoryStream();
using (var deflate = new DeflateStream(output, CompressionMode.Compress))
{
    deflate.Write(dataToCompress);
}
return output.ToArray();

Если необходимо различать пустые и непустые сжатые потоки, отслеживайте, были ли записаны какие-либо данные или проверьте исходную длину несжатых данных перед сжатием.

Затронутые API