添加具有 CompressionLevel 的 ZipArchiveEntry 时,会设置 ZIP 中央目录标头常规用途位标志

ZIP 文件规范指定应将嵌套文件记录的中央目录标头中常规用途位标志的位 1 和位 2 用于指示嵌套文件的压缩级别。

.NET Framework 在生成支持 ZipPackage API 的 ZIP 文件时会设置这些位。 在将 .NET Framework 代码迁移到 .NET 期间,此功能丢失,在 .NET 中,当 ZIP 文件中创建新文件记录时,位 1 和 2 始终被设置为 0。 此中断性变更可恢复该功能。 但是,调用 ZipArchive.CreateEntry 时指定 CompressionOption 的现有 .NET 客户端会看到常规用途位标志值更改。

旧行为

之前,.NET 会为已在 ZipArchive 中的每个 ZipArchiveEntry 保留常规用途位(在其加载时以及添加新条目时)。 但是,调用 ZipArchive.CreateEntry(String, CompressionLevel) 总是导致位 1 和 2 最后使用默认值 0,即使使用的是 CompressionLevel 而非 CompressionLevel.Optimal 也是如此。

此行为会产生一个下游效果:调用具有任何 CompressionOptionPackage.CreatePart(Uri, String, CompressionOption) 会导致位 1 和 2 未设置(因此 CompressionOption 会始终作为 CompressionOption.Normal 保存到 ZIP 文件中)。

新行为

从 .NET 9 开始,CompressionLevel 参数会映射到常规用途位标志,如下表所示。

CompressionLevel 位 1 位 2
NoCompression 0 0
Optimal 0 0
SmallestSize 1 0
Fastest 1 1

如果调用 ZipArchive.CreateEntry(String, CompressionLevel) 并指定 CompressionLevel.NoCompression,则嵌套文件记录的压缩方法将设置为 Stored(而非默认值 Deflate)。

如果添加了新的 ZipArchiveEntry,仍会为 ZipArchive 中已存在的 ZipArchiveEntry 记录保留常规用途位。

Package.CreatePart(Uri, String, CompressionOption) 中的 CompressionOption 枚举值映射到 CompressionLevel(其结果是设置相应的位),如下表所示。

CompressionOption CompressionLevel
NotCompressed NoCompression
Normal Optimal
Maximum SmallestSize (.NET Framework)
Optimal (.NET)
Fast Fastest
SuperFast Fastest

引入的版本

.NET 9 预览版 5

中断性变更的类型

此更改为行为更改

更改原因

引入了此中断性变更旨在还原现有 .NET Framework 行为,此前 .NET 中在移植时会省略该行为。 此更改还使下游客户端(例如 System.IO.Packaging)可以控制这些位的值。

如果要确保添加到 ZipArchive 的新 ZipArchiveEntry 记录具有常规用途位标志 0,请在调用 ZipArchive.CreateEntry(String, CompressionLevel) 时指定 CompressionLevel.OptimalCompressionLevel.NoCompressionCompressionLevel

如果使用 Package.CreatePart(Uri, String, CompressionOption) 将部件添加到 OPC 包,请指定 CompressionOption.NotCompressedCompressionOption.NormalCompressionOption

受影响的 API