2008-09-30 16 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); 
      } 
相關問題