【发布时间】:2018-07-25 05:50:14
【问题描述】:
如何解压下载的压缩文件(使用 Deflate 方法压缩,ANSI 编码)具有以下文件特征:
- 动态扩展(例如 .23U 或 .23M)
- 使用 Deflate 方法压缩和 ANSI 编码
- 可以通过 7-Zip 作为存档打开,但打开解压缩后仍然无法阅读。
以及以下技术要点:
- 以任何方式使用 DeflateStream 都不起作用
- 使用 GZipStream 是为了 .gz
- DotNetZip 库经常被推荐,但它太重而无法引用该项目(并且没有真正记录)
在另一个 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 139 142 69 119 119 119 119 119 119 119 135 32 8 136 10 38 2 10 38 138 138 29 32 234 59 231 210 189 55 107 242 187 246 251 158 115 158 231 60 239 255
这是我得到的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");
}
}
在这两种情况下,它都会给出“块长度与其补码不匹配”错误。但是,这是 Microsoft 推荐的方法,它应该以这种方式工作。 我意识到如果我消耗前两个字节,它不会给出那个错误,而是会导致一个空字符串......
编辑:
我显然在使用“正确”的 zip 文件时遇到了同样的问题(即使其他人已经成功使用了相同的算法),所以我将尝试使用外部解压缩库。
编辑
它与 Lasse Vågsæther Karlsen 建议的 Class ZipArchive 一起使用,他的代码在解压后获取数据方面的工作效率是 10/10。 现在剩下的就是能够拥有可理解的数据。我实际上对数据了解不多,除了:
- 记事本告诉我它是 ANSI 编码的
当我在提取文件后在 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());
它们都没有给出可以理解的字符链。
【问题讨论】:
-
在读取数据时扩展并不重要。只要文件是解压器能理解的格式。
-
这不是您在 SO 上提出此类问题的方式。您需要示例输入(文件、字符串)、到目前为止尝试过的代码(即使不工作)以及预期的输出。
-
我仍然不太确定该文件是只是扩展名已更改的 zip 文件还是完全不同的压缩格式。如果本质上是一个 zip 文件,
System.IO.Compression.ZipFile有什么问题? -
顺便说一句:如果您的文件格式不是真正的 zip,而是一些自定义压缩,那么通过从 C# 桥接到本机 dunzip.dll来利用唯一的工作软件怎么样>?
-
但是如果这是一个 zip 文件,为什么不使用任何 zip 归档类来处理它呢? zip 文件格式不仅仅是简单的压缩数据。试试
ZipArchive类。
标签: c# archive unzip compression deflate