2008-09-30 74 views
0

我正在使用SharpZipLib版本0.85.5来解压缩文件。我的代码在几个月前一直运行良好,直到我找到一个不喜欢的ZIP文件。SharpZipLib - ZipException“额外数据结束” - 为什么我得到这个异常?

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()

回答

1

其他zip工具可能会忽略额外的数据,这些数据已损坏 - 或者同样可能的是,#ZipLib中存在一个错误。 (我前一段时间发现 - 某个文件不会压缩,然后通过某些选项进行干净地解压缩。)

在这种特殊情况下,我建议您在#ZipLib论坛上发帖以获得开发者的关注。如果你的文件没有包含任何敏感数据,并且你可以随身携带一个简短但完整的程序,我认为这会有很大的帮助。

0

我同意乔恩。可能不适合在评论如下:

(虽然这并不能回答你的问题) 是不是更容易使用是这样的:

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); 
    } 
} 
0

official ZIP specification

ZIP档案中的每个文件都可以有一个与其关联的“额外”字段。我认为#ZipLib告诉你,给出的'额外'字段长度比可供读取的数据量要长;换句话说,ZIP文件最有可能被截断。

0

official ZIP specification 4.5.3,大小字段额外数据的& CompressedSize“如果相应的本地或中央目录记录字段设置为0xFFFF或0xFFFFFFFF必须只”。

但是SharpZipLib只有在“useZip64_ == UseZip64.On”时才在ZipFile.WriteCentralDirectoryHeader方法中写入它。我添加了entry.IsZip64Forced()条件和bug消失)

  if (entry.CentralHeaderRequiresZip64) { 
      ed.StartNewEntry(); 

      if ((entry.Size >= 0xffffffff) || (useZip64_ == UseZip64.On) || entry.IsZip64Forced()) 
      { 
       ed.AddLeLong(entry.Size); 
      } 

      if ((entry.CompressedSize >= 0xffffffff) || (useZip64_ == UseZip64.On) || entry.IsZip64Forced()) 
      { 
       ed.AddLeLong(entry.CompressedSize); 
      } 
相关问题