使用C#(.NET 4.6)压缩含非ASCII字符文件名文件的编码问题
解决.NET 4.6下C#压缩文件文件名乱码且UTF8编码不支持的问题
我之前也碰到过.NET 4.6里ZipFile的这个编码坑,确实挺头疼的——毕竟官方的ZipFile类在4.6版本里没给直接指定UTF8的入口,默认用的是IBM437(DOS编码),对中文这类非ASCII字符完全不友好,才会出现你看到的乱码;而你尝试给ZipFile.Open传UTF8编码时报错,是因为这个重载参数是.NET Framework 4.7才新增的,4.6根本不支持。
不用第三方库的话,我们可以直接用底层的ZipArchive类来实现,它在.NET4.6里已经支持指定编码了,具体步骤如下:
创建UTF8编码的压缩包
using (var zipFileStream = new FileStream("output.zip", FileMode.Create)) { // 实例化ZipArchive时指定UTF8编码,确保文件名以UTF8存储 using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create, Encoding.UTF8)) { // 添加单个文件到压缩包,文件名会正常保留 var entry = archive.CreateEntryFromFile("示例文件.csv", "示例文件.csv"); // 批量添加文件的话,循环调用CreateEntryFromFile即可 // archive.CreateEntryFromFile("其他文件.txt", "其他文件.txt"); } }
读取UTF8编码的压缩包(避免读取时乱码)
如果之后需要读取这个压缩包,同样要指定UTF8编码打开,否则还是会出现乱码:
using (var zipFileStream = new FileStream("output.zip", FileMode.Open)) { using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Read, Encoding.UTF8)) { foreach (var entry in archive.Entries) { // 此时entry.Name会正确显示中文文件名 Console.WriteLine($"文件名:{entry.Name}"); // 读取文件内容的示例代码 using (var entryStream = entry.Open()) using (var reader = new StreamReader(entryStream)) { var content = reader.ReadToEnd(); // 处理文件内容逻辑 } } } }
关键说明
ZipArchive在.NET Framework 4.5及以上就支持指定编码的构造函数,所以4.6版本完全兼容;- 必须保证创建和读取压缩包时都指定
Encoding.UTF8,否则会因编码不匹配再次出现乱码; - 这种方式和
ZipFile的底层实现逻辑一致,只是绕开了ZipFile在4.6版本的参数限制,完全不需要依赖第三方库。
内容的提问来源于stack exchange,提问作者Leonard AB
相关产品推荐
相关产品推荐

