You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C# ExtractToDirectory解压含特殊符号文件名的压缩包异常

解决C# ZipFile.ExtractToDirectory解压特殊字符文件名乱码问题

问题原因

.NET自带的ZipFile.ExtractToDirectory方法在处理包含非拉丁字符(如τ、ƒ)、特殊符号及Unicode字符的Zip文件时,存在编码检测局限性:

  • 传统Zip格式默认使用CP437编码,但若文件实际采用UTF-8存储却未在Zip头标记UTF-8属性,ZipFile会强制用指定编码解析,导致文件名失真。
  • Windows资源管理器和TotalCommander采用了更智能的编码自动检测逻辑(如优先尝试UTF-8、系统默认编码),因此能正确识别文件名。

解决方案

方案1:使用第三方压缩库(推荐)

第三方库如SharpZipLib或DotNetZip对Zip编码的支持更完善,能自动识别UTF-8标记或兼容传统编码。以SharpZipLib为例:

  1. 安装NuGet包:Install-Package SharpZipLib
  2. 编写解压代码:
using ICSharpCode.SharpZipLib.Zip;
using System.IO;

public void ExtractZipCorrectly(string zipFilePath, string destDirectory)
{
    Directory.CreateDirectory(destDirectory);
    
    using (var zipStream = new ZipInputStream(File.OpenRead(zipFilePath)))
    {
        ZipEntry entry;
        while ((entry = zipStream.GetNextEntry()) != null)
        {
            // SharpZipLib会自动检测UTF-8标记,无需手动指定编码
            var fullFilePath = Path.Combine(destDirectory, entry.Name);
            
            if (entry.IsDirectory)
            {
                Directory.CreateDirectory(fullFilePath);
                continue;
            }
            
            // 创建父目录(避免文件路径含子目录时出错)
            Directory.CreateDirectory(Path.GetDirectoryName(fullFilePath));
            
            using (var fileStream = File.Create(fullFilePath))
            {
                zipStream.CopyTo(fileStream);
            }
        }
    }
}

方案2:手动使用ZipArchive解析条目

若不想引入第三方库,可直接用ZipArchive逐个处理条目,它会优先检查Zip头的UTF-8标记,而非强制使用指定编码:

using System.IO.Compression;
using System.IO;

public void ExtractWithZipArchive(string zipFilePath, string destDirectory)
{
    Directory.CreateDirectory(destDirectory);
    
    using (var archive = ZipFile.OpenRead(zipFilePath))
    {
        foreach (var entry in archive.Entries)
        {
            var destPath = Path.Combine(destDirectory, entry.FullName);
            
            // 处理目录条目
            if (entry.FullName.EndsWith("/"))
            {
                Directory.CreateDirectory(destPath);
                continue;
            }
            
            // 确保父目录存在
            Directory.CreateDirectory(Path.GetDirectoryName(destPath));
            // 提取文件
            entry.ExtractToFile(destPath, overwrite: true);
        }
    }
}

关键说明

  • 避免直接使用ZipFile.ExtractToDirectory的encoding参数:该参数会强制覆盖自动检测逻辑,反而可能导致编码不匹配。
  • 若方案2仍无效,可尝试手动指定ZipArchive的编码为Encoding.UTF8或系统默认编码(如Encoding.GetEncoding(1252)),但需根据实际Zip文件的编码情况调整。

内容的提问来源于stack exchange,提问作者Alex Ink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:34:55