Freigeben über


DeflateStream und GZipStream schreiben Kopf- und Fußzeilen für leere Datenlast

DeflateStream und GZipStream schreiben jetzt immer Formatkopf- und Fußzeilen in den Ausgabedatenstrom, auch wenn keine Daten geschrieben werden. Dadurch wird sichergestellt, dass die Ausgabe ein gültiger komprimierter Datenstrom gemäß den Spezifikationen "Deflate" und "GZip" ist.

Eingeführt in Version

.NET 11 Preview 1

Vorheriges Verhalten

Zuvor erzeugten DeflateStream und GZipStream keine Ausgabe, wenn keine Daten in den Datenstrom geschrieben wurden. Dies führte zu einem leeren Ausgabedatenstrom beim Komprimieren einer leeren Eingabe.

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

Neues Verhalten

Beginnend mit .NET 11 schreiben DeflateStream und GZipStream immer die entsprechenden Kopf- und Fußzeilen in den Ausgabedatenstrom, auch wenn keine Daten geschrieben werden. Dadurch wird sichergestellt, dass die Ausgabe gültige komprimierte Daten gemäß den Formatspezifikationen enthält.

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).

Art der einschneidenden Änderung

Diese Änderung ist eine Verhaltensänderung.

Grund für Änderung

Deflate- und GZip-Komprimierungsformate umfassen Trennzeichen für den Anfang und das Ende komprimierter Daten. Die richtige Methode zum Komprimieren einer leeren Nutzlast mit diesen Formaten umfasst nur diese Trennzeichen. Einige Tools reagieren nicht ordnungsgemäß auf leere Inhalte und erwarten immer, dass der komprimierte Inhalt mindestens die entsprechende Kopf- und Fußzeile enthält. Diese Änderung gewährleistet die Kompatibilität mit solchen Tools und erzeugt ordnungsgemäß formatierte komprimierte Datenströme gemäß den Spezifikationen.

Wenn das vorherige Verhalten gewünscht wird, sollte leerer Inhalt als Sonderfall betrachtet werden, um ihn nicht über DeflateStream oder GZipStream zu komprimieren.

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();

Wenn Sie zwischen leeren und nicht leeren komprimierten Datenströmen unterscheiden müssen, können Sie nachverfolgen, ob Daten vor der Komprimierung geschrieben wurden oder ob die ursprüngliche nicht komprimierte Datenlänge überprüft wurde.

Betroffene APIs