c# - ZipFile ExtractToDirectory 错误的文件夹名称 Unicode
问题描述
我有 zip 存档,里面有文件夹。文件夹名称包含 unicode 字符(格鲁吉亚字母)。当我提取它时,我得到了错误的文件夹名称。例如
存档中的文件夹名称:6001 SAHIN INOX 192MM სახელური
提取的文件夹名称:6001 SAHIN INOX 192MM fossyhew
创建存档的机器和我试图提取它的机器是不同的。这是我尝试过的所有不同选项的代码,但没有一个有效。
static void Main(string[] args)
{
var ZipFilePath = $"1.zip";
ZipFile.ExtractToDirectory(ZipFilePath, AppDomain.CurrentDomain.BaseDirectory);
//ZipFile.ExtractToDirectory(ZipFilePath, AppDomain.CurrentDomain.BaseDirectory, Encoding.UTF8);
//ZipFile.ExtractToDirectory(ZipFilePath, AppDomain.CurrentDomain.BaseDirectory, new UTF8Encoding());
//ZipFile.ExtractToDirectory(ZipFilePath, AppDomain.CurrentDomain.BaseDirectory, Encoding.GetEncoding(1252));
//ZipFile.ExtractToDirectory(ZipFilePath, AppDomain.CurrentDomain.BaseDirectory, Encoding.GetEncoding(850));
}
存档网址:1.zip
项目网址:Project.zip
有任何想法吗?
解决方案
我只花了一个小时调试 .NET 源代码,看看发生了什么。
首先要注意的是 ZIP 目录标题中的文件名包含“fossyhew”——这就是值的来源!
如果我们查看目录标题中条目的额外字段,我们可以看到有一个带有标记 0x7075 的条目,其中包含您的 UTF-8 文件名:
深入规范,0x7075 是“Info-ZIP Unicode Path Extra Field”(参见第 4.6.9 节),它是包含 UTF-8 版本文件名的扩展名:
UnicodeName 是标头中文件名字段内容的 UTF-8 版本。由于 UnicodeName 被定义为 UTF-8,因此不使用 UTF-8 字节顺序标记 (BOM)。该字段的长度是通过从 TSize 中减去先前字段的大小来确定的。如果文件名和注释字段都是 UTF-8,则新的通用位标志位 11(语言编码标志 (EFS))可用于指示标题文件名和注释字段都是 UTF-8 和,在这种情况下,不需要并且不应创建 Unicode 路径和 Unicode 注释额外字段。请注意,为了向后兼容,只有在被压缩的路径和注释的本地字符集已经是 UTF-8 时,才应该使用第 11 位。预计相同的文件名存储方法,无论是通用位 11 还是额外字段,
问题是,ZipArchive
不支持从额外字段中读取文件名 - 读取它们的唯一原因是如果您正在更新存档,因此可以将它们写回。ZipArchive
但是确实支持通用位 11(它只是用来强制 UTF-8 解码)。
因此,总而言之,有两种方法可以在 ZIP 中设置 UTF-8 文件名:您的存档决定使用的一种方法将文件名指定为代码页 437(这是“fossyhew”的来源)和 UTF-8在一个额外的领域。ZipArchive
不支持从这个额外的字段读取。
推荐阅读
- node.js - 通过从 Node JS 获取路径在 React 中打开 pdf
- php - 同一方法中具有不同返回类型的接口的 PHP 父接口
- python - 为什么棱镜不突出蟒蛇?
- azure-data-factory - 如何将获取元数据结构输出与已知结构进行比较以验证文件?
- oracle - 在 SQL 表中输入序列,错误 - ORA-01858:在需要数字的地方发现了一个非数字字符
- reference - Visual Studio Nuget 在引用属性中恢复无路径
- python - 在python中为字符串字段创建嵌套列表
- excel - VBA:如何循环搜索 7 天(日复一日)的日期?
- java - SimpleStringProperty 在类外返回 null
- python - 有没有办法通过python登录网站