System.IO.Compression.ZipFile .NET 4.5 output zip in not suitable for Linux/Mac/Java

后端 未结 3 1440
清酒与你
清酒与你 2021-02-07 04:07

While using .NET System.IO.Compression.ZipFile.CreateFromDirectory class the outcome zip is badly extracted on system with forward-slash directory separator.

相关标签:
3条回答
  • 2021-02-07 04:28

    The correct work around for this issue is as follows

    class MyEncoder : UTF8Encoding
    {
        public MyEncoder() : base(true)
        {
    
        }
        public override byte[] GetBytes(string s)
        {
            s = s.Replace("\\", "/");
            return base.GetBytes(s);
       }
    }
    

    NOTE: This is slightly different from a previous answer.

    The key difference is in the : base(true)

    This is important or the .NET ZipArchive class will NOT recognize the encoder as a UTF-8 encoder and will NOT mark the correct general purpose bit, and thus extracting the resulting zip file with any other zip program will assume the zip entry name is in a non-unicode encoding which might result in a mangled filename.

    The reason is due to a internal call in .NET to check if the custom encoder is .equals(Encoding.UTF8) which isn't true unless true is passed for the encoderShouldEmitUTF8Identifier like Encoding.UTF8

    0 讨论(0)
  • 2021-02-07 04:33

    Microsoft has addressed this in .NET 4.6.1:

    Starting with apps that target the .NET Framework 4.6.1, the path separator used in the ZipArchiveEntry.FullName property has changed from the backslash ("\") used in previous versions of the .NET Framework to a forward slash ("/"). System.IO.Compression.ZipArchiveEntry objects are created by calling one of the overloads of the ZipFile.CreateFromDirectory method.

    Note:

    In addition, apps that target previous versions of the .NET Framework but are running on the .NET Framework 4.6.1 and later versions can opt in to this behavior by adding a configuration setting to the section of the application configuration file.

    0 讨论(0)
  • 2021-02-07 04:52

    To overcome this problem a workaround exists:

        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());
    
    0 讨论(0)
提交回复
热议问题