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

让人想犯罪 __ 提交于 2020-03-17 08:15:06

问题


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

Reason: The zip contains backslash inside the names


回答1:


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());



回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/27289115/system-io-compression-zipfile-net-4-5-output-zip-in-not-suitable-for-linux-mac

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!