代码之家  ›  专栏  ›  技术社区  ›  Seibar

SharpZipLib-ZipException“额外数据结束”-为什么我会得到这个异常?

  •  0
  • Seibar  · 技术社区  · 16 年前

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

    4 回复  |  直到 16 年前
        1
  •  1
  •   Jon Skeet    16 年前

    可能是其他zip工具忽略了损坏的额外数据,也可能是ZipLib中有一个bug。(我不久前发现了一个——一个不会压缩的特定文件,然后使用特定选项彻底解压缩。)

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

        2
  •  0
  •   Vivek    16 年前

    我同意乔恩的看法。无法在评论中包含以下内容:

    (尽管这不能回答你的问题) 使用这样的东西不是更容易吗:

    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);
        }
    }
    
        3
  •  0
  •   Mike Dimmick    16 年前

    official ZIP specification .

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

        4
  •  0
  •   Barmaley A    9 年前

    根据4.5.3 official ZIP specification

    但是 SharpZipLib 仅当“useZip64==useZip64.On”时,才写入其at方法ZipFile.writeEntralDirectoryHeader。我补充说 entry.IsZip64Forced() 条件和缺陷消失)

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