SharpZipLib-ZipException"额外数据的结尾"-为什么会收到此异常?

时间:2020-03-06 14:56:27  来源:igfitidea点击:

我正在使用SharpZipLib 0.85.5版解压缩文件。我的代码已经运行了好几个月了,直到我找到了它不喜欢的ZIP文件。

ICSharpCode.SharpZipLib.Zip.ZipException: End of extra data     
    at ICSharpCode.SharpZipLib.Zip.ZipExtraData.ReadCheck(Int32 length) in C:\C#\SharpZLib\Zip\ZipExtraData.cs:line 933     
    at ICSharpCode.SharpZipLib.Zip.ZipExtraData.Skip(Int32 amount) in C:\C#\SharpZLib\Zip\ZipExtraData.cs:line 921     
    at ICSharpCode.SharpZipLib.Zip.ZipEntry.ProcessExtraData(Boolean localHeader) in C:\C#\SharpZLib\Zip\ZipEntry.cs:line 925     
    at ICSharpCode.SharpZipLib.Zip.ZipInputStream.GetNextEntry() in C:\C#\SharpZLib\Zip\ZipInputStream.cs:line 269     
    at Constellation.Utils.Tools.UnzipFile(String sourcePath, String targetDirectory) in C:\C#\Constellation2\Utils\Tools.cs:line 90     
--- End of inner exception stack trace ---

这是我的解压缩方法:

public static void UnzipFile(string sourcePath, string targetDirectory)
     {
        try
        {
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourcePath)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    //string directoryName = Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);

                    if (targetDirectory.Length > 0)
                    {
                        Directory.CreateDirectory(targetDirectory);
                    }

                    if (fileName != String.Empty)
                    {
                        using (FileStream streamWriter = File.Create(targetDirectory + fileName))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error unzipping file \"" + sourcePath + "\"", ex);
        }
    }

使用XP的内置ZIP支持,WinZIP和7-Zip,该文件可以很好地解压缩。异常被抛出在s.GetNextEntry()上。

解决方案

其他zip工具可能会忽略多余的数据,这些数据已损坏,或者#ZipLib中也存在错误。 (我前一段时间找到了一个不会压缩的文件,然后使用某些选项进行了干净的解压缩。)

在这种情况下,建议我们发布在#ZipLib论坛上,以吸引开发人员的注意。如果文件不包含任何敏感数据,并且我们可以将它们与简短但完整的程序一起获取,我怀疑这将有很大帮助。

我同意乔恩的观点。无法在评论中加入以下内容:

(尽管这不能回答问题)
使用这样的东西难道不是很容易吗?

public static void UnzipFile(string sourcePath, string targetDirectory)
{
    try
    {
        FastZip fastZip = new FastZip();
        fastZip.CreateEmptyDirectories = false;
        fastZip.ExtractZip(sourcePath, targetDirectory,"");
    }
    catch(Exception ex)
    {
        throw new Exception("Error unzipping file \"" + sourcePath + "\"", ex);
    }
}

请参阅官方ZIP规范。

ZIP归档文件中的每个文件都可以有一个与之关联的"额外"字段。我认为#ZipLib告诉我们,给定的"额外"字段长度比可读取的数据量长;换句话说,ZIP文件很可能已被截断。