一个讨厌的编码问题

编码问题很讨厌。昨天就碰到了一个,花了几个小时才解决。

使用DotNetZip这个库自动打包文件夹,原来的代码是:

1
2
3
4
5
6
var dir = new DirectoryInfo(@"c:\foo");
using (ZipFile zip = new ZipFile(Encoding.UTF8))
{
    var entry = zip.AddDirectory(dir.FullName, dir.Name);
    zip.Save(Path.Combine(path, dir.Name + ".zip"));
}

看上去很正常,也似乎能work,成功打包,用7-zip打开,里面的中文文件夹也显示正常。

但是,如果是用7-zip手工打包的zip,在资源管理器里双击可以看到里面的文件夹。而这个用代码生成的zip,如果打包进去的是中文文件夹,双击却显示空白。这似乎不成问题,但因为我打包的都是pdg文件(某电子书格式文件,不懂的一搜便知),本来直接把zip后缀改成uvz,便可用一个叫做UnicornViewer的软件阅读,而这个用代码生成的zip,改名后却用UnicornViewer打不开,提示打开失败。

英文文件夹可以,中文文件夹不行,似乎很可能是“编码问题”。

用下面的代码查看zip的属性:

1
2
3
4
5
6
7
8
9
10
using (ZipFile zip = ZipFile.Read("foo.zip")))
{
    foreach (ZipEntry entry in zip)
    {
        if (entry.IsDirectory)
        {//这里加上断点,以便查看entry的属性
            break;
        }
    }
}

结果发现,用7-zip打包的文件,entry的AlternateEncoding显示为IBM437,FileName属性显示为乱码,比如“世界第一位六冠王赵国荣实战专辑”,显示为“╩└╜τ╡┌╥╗╬╗┴∙╣┌═⌡╒╘╣·╚┘╩╡╒╜╫¿╝¡”。

查了很多资料,调试了半天,最后终于理解了,原来这是用IBM437去解码gb2312/gbk编码的字符串的结果。理解了这一点,修改代码:

1
2
3
4
5
6
7
8
9
var dir = new DirectoryInfo(@"c:\foo");
byte[] bytes = Encoding.GetEncoding("gb2312").GetBytes(dir.Name.ToCharArray());
string newName = Encoding.GetEncoding("IBM437").GetString(bytes);
using (ZipFile zip = new ZipFile(Encoding.UTF8))
{
    zip.AlternateEncoding = Encoding.GetEncoding("IBM437");
    var entry = zip.AddDirectory(dir.FullName, newName);
    zip.Save(Path.Combine(path, dir.Name + ".zip"));
}

测试通过。

以前碰到的编码问题,多是将乱码转成正常显示的字符,这次却要故意生成“乱码”才能工作正常,呵呵。管他呢,反正it just works。

posted @   平静寄居者  阅读(172)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示