如何使用以下文件特征解压缩下载的压缩文件(使用Deflate方法压缩,ANSI编码):
以下技术要点:
在另一个c ++项目中(我实际上需要模仿C#中的行为),使用 dunzip.dll 库并导致可读字符。 我们可以在网上看到C#存在 dunzip32.dll libray,但是没有关于如何使用它的文档。
编辑:
以下是我从压缩文件中获取的字节数组的前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文件相同的问题(即使其他人使用相同的算法也取得了成功),所以我将尝试使用外部解压缩库。
修改
它正在使用LasseVågsætherKarlsen建议的Class ZipArchive,他的代码在解压缩后获取数据的工作正常。 现在剩下的就是能够获得可理解的数据。我实际上对数据知之甚少,除了:
当我在提取文件后在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());
他们都没有提供可理解的人物链。
答案 0 :(得分:2)
问题在于.ZIP文件不仅仅是简单的数据泄露。有目录结构,校验和,文件元数据等等。
您需要使用知道此结构的类。除非文件使用一些更高级的东西,例如加密和跨越档案,否则.NET ZipArchive类可能会起到作用。
这是一个简单的程序,它从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()));
}
}