在使用.NET System.IO.Compression.ZipFile.CreateFromDirectory类时,结果zip在带有正斜杠目录分隔符的系统上提取得很糟糕。
原因:zip 名称中包含反斜杠
要解决此问题,存在解决方法:
class MyEncoder : UTF8Encoding
{
public MyEncoder()
{
}
public override byte[] GetBytes(string s)
{
s = s.Replace("\", "/");
return base.GetBytes(s);
}
}
System.IO.Compression.ZipFile.CreateFromDirectory("C:/ABC", "C:/tmp/ABC.zip", CompressionLevel.Fastest, false, new MyEncoder());
Microsoft在.NET 4.6.1中解决了这个问题:
从面向 .NET Framework 4.6.1 的应用开始,ZipArchiveEntry.FullName 属性中使用的路径分隔符已从以前版本的 .NET Framework 中使用的反斜杠 ("\") 更改为正斜杠 ("/")。System.IO.Compression.ZipArchiveEntry 对象是通过调用 ZipFile.CreateFromDirectory 方法的重载之一创建的。
注意:
此外,面向以前版本的 .NET Framework 但在 .NET Framework 4.6.1 及更高版本上运行的应用可以通过向应用程序配置文件的部分添加配置设置来选择加入此行为。
此问题的正确解决方法如下
class MyEncoder : UTF8Encoding
{
public MyEncoder() : base(true)
{
}
public override byte[] GetBytes(string s)
{
s = s.Replace("\", "/");
return base.GetBytes(s);
}
}
注意:这与之前的答案略有不同。
关键区别在于: base(true)
这很重要,否则 .NET ZipArchive 类将无法将编码器识别为 UTF-8 编码器,并且不会标记正确的通用位,因此使用任何其他 zip 程序提取生成的 zip 文件将假定 zip 条目名称采用非 unicode 编码,这可能会导致文件名损坏。
原因是由于 .NET 中的内部调用以检查自定义编码器是否.equals(Encoding.UTF8)
,除非为编码器传递true
,否则该调用应发出UTF8标识符(如编码.UTF8