0

我正在使用 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()

4

4 回答 4

1

其他 zip 工具可能会忽略损坏的额外数据 - 或者 #ZipLib 中同样可能存在错误。(我不久前发现了一个 - 某个文件不会压缩,然后使用某些选项干净地解压缩。)

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

于 2008-09-30T19:23:47.497 回答
0

请参阅官方 ZIP 规范

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

于 2008-09-30T23:25:36.260 回答
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);
    }
}
于 2008-09-30T21:36:43.510 回答
0

根据官方 ZIP 规范4.5.3 ,额外数据的字段大小和压缩大小“必须仅在相应的本地或中央目录记录字段设置为 0xFFFF 或 0xFFFFFFFF 时出现”。

SharpZipLib仅当“useZip64_ == UseZip64.On”时才将其写入方法 ZipFile.WriteCentralDirectoryHeader。我添加了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);
            }
于 2015-06-19T09:12:56.683 回答