问题描述
当我使用7-zip打开它时,它可以正常工作,但是属性中存在警告-“有效负载数据结束后有一些数据”
但是当我尝试使用DotNetZip解压缩它时,会给我一个错误
using (var zip = ZipFile.Read("test.ef4"))
{
foreach (var zipEntry in zip)
{
Console.WriteLine(zipEntry.FileName);
var MemoryStream = new MemoryStream();
zipEntry.OpenReader().copyTo(MemoryStream);
File.WriteallBytes(zipEntry.FileName,MemoryStream.ToArray());
}
}
Exception:
Unhandled Exception: Ionic.Zip.ZipException: Cannot read that as a ZipFile
---> Ionic.Zip.BadReadException: Bad signature (0x0C000001) at position 0x00000060
我该如何忽略此异常并像7-zip一样从文件中解压缩?
要重现它,可以使用Windows cmd.exe创建存档
使用一些随机数据创建archive.zip和exTradata.txt。然后执行以下命令-
copy /b archive.zip+exTradata.txt
解决方法
我找到了适合我的解决方案:
在我的情况下,所有zip文件都具有\ x50 \ x4b \ x01 \ x02或\ x50 \ x4b \ x03 \ x04之类的标头。 (前\ x50 \ x4b始终相同。后半部分可以不同)
所以我写了一个代码,该代码在字节内找到我的ZIP文件的偏移量。文件的页脚对于C#中的任何ziplib都不重要
class Program
{
static void Main(string[] args)
{
var content = File.ReadAllBytes("qv.zip");
content = content.Skip(FirstPattern(content)).ToArray();
using (var zip = ZipFile.Read(new MemoryStream(content),new ReadOptions() {}))
{
foreach (var zipEntry in zip)
{
Console.WriteLine(zipEntry.FileName);
var MemoryStream = new MemoryStream();
zipEntry.OpenReader().CopyTo(MemoryStream);
File.WriteAllBytes(zipEntry.FileName,MemoryStream.ToArray());
}
}
}
private static int FirstPattern(byte[] bytes)
{
var header = StringToByteArray("504b0304"); // In my case all broken zip-files had 0304 ending
for (int i = 0; i < bytes.Length - header.Length; i++)
{
var j = 0;
while(j < header.Length && bytes[i + j] == header[j])
{
j++;
}
if(j == header.Length
return i;
}
return -1;
}
public static byte[] StringToByteArray(string hex)
{
int numberChars = hex.Length;
byte[] bytes = new byte[numberChars / 2];
for (int i = 0; i < numberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i,2),16);
return bytes;
}
}