Skip to content
Go back

.NET 10 的 Zip 与 GZip 压缩改进

日常开发里,压缩常常是看不见的基础设施。打包构建产物、备份数据、压缩日志、在网络上传输数据,这些场景都离不开 ZipArchiveGZipStream

Anthony Giretti 的文章提到一个很实用的变化:.NET 10 基本不动这些 API 的表面形状,但在实现细节上做了优化。你的代码大概率不用改,升级目标框架就能更快。

背景

在旧版本 .NET 中,压缩相关 API 能工作,也足够稳定,但在一些常见工作流上会遇到瓶颈。

例如:

.NET 10 主要改进点

这次改进的核心方向很明确。

同时,作者强调了一点:公开 API 设计目标是保持兼容。

示例 1:异步解压 zip

下面的写法在很多项目里都见过。重点在于 .NET 10 里这段逻辑通常会跑得更顺。

using System;
using System.IO;
using System.IO.Compression;
using System.Threading;
using System.Threading.Tasks;

public static class ZipExtractor
{
    public static async Task ExtractZipAsync(
        string zipPath,
        string destination,
        CancellationToken ct = default)
    {
        Directory.CreateDirectory(destination);

        await using var fs = File.OpenRead(zipPath);
        using var archive = new ZipArchive(fs, ZipArchiveMode.Read, leaveOpen: false);

        foreach (var entry in archive.Entries)
        {
            // 跳过目录条目
            if (string.IsNullOrEmpty(entry.Name))
                continue;

            var outPath = Path.Combine(destination, entry.FullName);
            Directory.CreateDirectory(Path.GetDirectoryName(outPath)!);

            await using var entryStream = entry.Open();
            await using var outStream = File.Create(outPath);

            await entryStream.CopyToAsync(outStream, ct);
            Console.WriteLine($"Extracted: {entry.FullName}");
        }
    }
}

await ZipExtractor.ExtractZipAsync("sample.zip", "./out", CancellationToken.None);

如果你经常在慢磁盘、网络盘、容器卷里解压,或者 zip 里有很多小文件,这类优化会更容易感知。

示例 2:读取拼接式 gzip

不少工具会输出拼接式 gzip。它看起来像一个 .gz 文件,内部却是多个 gzip member 顺序拼起来。

flowchart LR
  A[member 1\nheader + data + trailer] --> B[member 2\nheader + data + trailer] --> C[member 3\nheader + data + trailer]

.NET 10 对这类文件的处理更高效。代码仍然很朴素。

using System;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Threading.Tasks;

static async Task ReadConcatenatedGzipAsync(string path)
{
    await using var fileStream = File.OpenRead(path);
    await using var gzip = new GZipStream(fileStream, CompressionMode.Decompress);
    using var reader = new StreamReader(gzip, Encoding.UTF8);

    var content = await reader.ReadToEndAsync();
    Console.WriteLine(content);
}

await ReadConcatenatedGzipAsync("data.gz");

如果你的系统要处理按时间切分后再拼接的日志 gzip,这个变化会更有价值。

实践建议

升级到 .NET 10 之前和之后,写法上可以保持一致,但有几条建议值得顺手检查一下。

小结

.NET 10 对 ZipArchiveGZipStream 的改进属于升级就赚到的类型:API 基本不变,但更快、更省、更适合现实世界的文件形态。

原文链接:https://anthonygiretti.com/2026/01/19/net-10-zip-and-gzip-api-improvements


Tags


Next

Playwright CLI:面向编码代理的高效浏览器自动化工具