System.IO.Compression.ZipFile .NET 4.5输出zip不适合Linux/Mac/Java

Adi*_*diA 19 .net zipfile

在使用.NET System.IO.Compression.ZipFile.CreateFromDirectory类时,使用正斜杠目录分隔符在系统上严重提取结果zip.

原因:zip在名称中包含反斜杠

Adi*_*diA 17

为了解决这个问题,存在一种解决方法:

    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());
Run Code Online (Sandbox Code Playgroud)

  • 没有?该编码器仅用于文件名条目.UTF8不在原始规范中,因此有大量的zip软件无法读取UTF8编码的文件名,这仅在文件名包含"本机编码"未处理的内容时才有意义.不过,我不知道编码是什么. (4认同)
  • @Lasse - 非常欢迎您查看...开始时我们运行一个简单的System.IO.Compression.ZipFile.CreateFromDirectory("C:/ ABC","c:/tmp/abc.zip")只要你不在linux/Mac等下使用它' (2认同)
  • 为什么.NET的默认设置使其与Mac不兼容,而其他所有ZIP解决方案(WinRAR,7-Zip等)都会生成在两个系统上都能正常提取的zip文件.为什么.NET会为编码路径分隔符字符选择最不兼容的默认值?此解决方法至少有效. (2认同)

小智 12

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及更高版本上运行的应用程序可以通过向应用程序配置文件的部分添加配置设置来选择此行为.

  • 我怎么能用PowerShell做到这一点?我有PS 5但它看起来仍然使用破损的拉链版本? (6认同)

Mer*_*OWA 10

对此问题的正确解决方法如下

class MyEncoder : UTF8Encoding
{
    public MyEncoder() : base(true)
    {

    }
    public override byte[] GetBytes(string s)
    {
        s = s.Replace("\\", "/");
        return base.GetBytes(s);
   }
}
Run Code Online (Sandbox Code Playgroud)

注意:这与之前的答案略有不同.

关键的区别在于 : base(true)

这很重要,或者.NET ZipArchive类不会将编码器识别为UTF-8编码器,并且不会标记正确的通用位,因此使用任何其他zip程序提取生成的zip文件将假定zip条目名称在非unicode编码,可能导致文件名错误.

原因是由于在.NET中进行内部调用以检查自定义编码器是否.equals(Encoding.UTF8)为真,除非true传递给encoderShouldEmitUTF8Identifier,如Encoding.UTF8