解压缩具有特定扩展名的文件(不是 .zip)

Unzip a file with a particular extension (not .zip)

如何解压下载的具有以下文件特征的压缩文件(使用Deflate方法压缩,ANSI编码):

以及以下技术要点

在另一个 c++ 项目中(我实际上需要模仿 C# 中的行为),使用了 dunzip.dll 库并生成可读字符。 我们可以在网上看到有一个dunzip32.dll C#的库,但是没有关于如何使用它的文档。

编辑:

这是我从压缩文件中获得的字节数组的前 100 个字节(十进制):

80 75 3 4 20 0 8 0 8 0 67 75 79 76 0 0 0 0 0 0 0 0 0 0 0 0 12 0 0 0 50 50 67 67 48 48 48 49 46 50 51 85 204 189 117 88 85 251 215 238 77 9 2 210 221 157 210 221 221 221 221 221 139 139 142 69 119 119 119 119 119 119 119 119 119 119 119 135 32 8 136 10 38 2 10 38 2 10 38 138 138 138 138 138 29 32 234 59 32 234 59 234 59 231 231 210 189 210 189 55 107 242 187 242 187 246 251 151 158 115 158 231 60 239 255

这是我得到的 hexa 前 100 个字节的报告:

0000-0010:  50 4b 03 04-14 00 08 00-08 00 60 4b-47 4c 00 00  PK...... ..`KGL..
0000-0020:  00 00 00 00-00 00 00 00-00 00 0c 00-00 00 32 32  ........ ......22
0000-0030:  43 43 30 30-30 31 2e 32-33 55 cc bd-75 58 55 fb  CC0001.2 3U..uXU.
0000-0040:  d7 ee 4d 09-02 d2 dd 9d-d2 dd dd dd-8b 8e 45 77  ..M..... ......Ew
0000-0050:  77 77 77 77-77 77 87 20-08 88 0a 26-02 0a 26 8a  wwwwww.. ...&..&.
0000-0060:  8a 1d 20 ea-3b e7 d2 bd-37 6b f2 bb-f6 fb 9e 73  ....;... 7k.....s
0000-0064:  9e e7 3c ef                                      ..<.

它以 50 4b 03 04 开头的事实意味着它是一种基于 zip 的格式: 然后,将其视为 zip 文件,我尝试使用 msdn 示例中的简单方法解压缩数据,在一种情况下使用 MemoryStream,在另一种情况下使用 FileStream。

public static string UnzipString3(byte[] byteArrayCompressedContent)
{
    using (var outputStream = new MemoryStream())
    {
        using (var compressStream = new MemoryStream(byteArrayCompressedContent))
        {
            using (var deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
            {
                deflateStream.CopyTo(outputStream);
            }
        }
        return Encoding.UTF8.GetString(outputStream.ToArray());
    }
}


public void UnzipProperZipFile()
{
        try
        {
            using (var outputStream = new MemoryStream())
            {
                FileInfo fileInfo = new FileInfo("NormalZip.zip");
                FileStream fileStream = fileInfo.OpenRead();
                fileStream.Position = 2;
                using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Decompress))
                {
                    deflateStream.CopyTo(outputStream);
                }
                string res = Encoding.UTF8.GetString(outputStream.ToArray());
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("errorlole");
        }
}

在这两种情况下,它都会给出“块长度与其补码不匹配”错误。然而,这是微软推荐的方法,应该是这样工作的。 我意识到,如果我使用前两个字节,它不会给出该错误,而是会导致一个空字符串...

编辑:

我显然在使用 "proper" zip 文件时遇到了同样的问题(即使其他人已经成功使用相同的算法),所以我将尝试使用外部解压缩库。

编辑

它正在与 Lasse Vågsæther Karlsen 建议的 Class ZipArchive 一起工作,并且他的代码在解压缩后获取数据时的工作效率为 10/10。 现在剩下的就是能够拥有可理解的数据。我实际上对数据了解不多,除了:

当我在提取文件后在 MemoryStream 中传输数据时,我尝试以所有使用的编码获取它;

entryStream.CopyTo(memoryStream);
string laChaineUTF8 = Encoding.UTF8.GetString(memoryStream.ToArray());
string laChaineDefault = Encoding.Default.GetString(memoryStream.ToArray());
string laChaineUnicode = Encoding.Unicode.GetString(memoryStream.ToArray());
string laChaineASCII = Encoding.ASCII.GetString(memoryStream.ToArray());
string laChaineBigEndianUnicode = Encoding.BigEndianUnicode.GetString(memoryStream.ToArray());
string laChaineUTF7 = Encoding.UTF7.GetString(memoryStream.ToArray());
string laChaineUTF32 = Encoding.UTF32.GetString(memoryStream.ToArray());

None 给出了一个可以理解的字符链。

问题在于 .ZIP 文件不仅仅是压缩数据。有目录结构、校验和、文件元数据等等

您需要使用了解此结构的 class。除非文件使用了一些更高级的东西,例如加密和跨越存档,否则 .NET ZipArchive class 可能会起作用。

这是一个从 zip 存档中提取文本文件内容的简单程序。您必须根据您的需要调整它:

using (var file = File.Open(@"D:\Temp\Temp.zip", FileMode.Open))
using (var archive = new ZipArchive(file))
{
    var entry = archive.GetEntry("ttt/README.md");
    using (var entryStream = entry.Open())
    using (var memory = new MemoryStream())
    {
        entryStream.CopyTo(memory);
        Console.WriteLine(Encoding.UTF8.GetString(memory.ToArray()));
    }
}