【问题标题】:DotNetZip BadReadException on .Extract.Extract 上的 DotNetZip BadReadException
【发布时间】:2013-03-11 11:14:18
【问题描述】:

我有一个奇怪的文件,当使用 DotNetZip 压缩时会创建一个“不可解压缩”的存档。当我尝试使用 7zip 解压缩它时,CRC failed in 'AjaxControlToolkit.dll'. File is broken. 会失败当我手动使用 7zip 压缩它时,它解压缩得很好。

有没有人遇到过 DotNetZip 无法正确压缩简单二进制文件的情况?还是我错误地使用了 DotNetZip?

https://dl.dropbox.com/u/65419748/AjaxControlToolkit.dll

using System.IO;
using Ionic.Zip;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var source = new FileInfo(@"C:\ZipDemo\AjaxControlToolkit.dll");
            var target = new FileInfo(Path.ChangeExtension(source.FullName, "zip"));
            var folder = new DirectoryInfo(Path.ChangeExtension(source.FullName, null));

            if (target.Exists)
                target.Delete();

            if (folder.Exists)
                folder.Delete(true);

            using (var zip = new ZipFile(target.FullName))
            {
                zip.AddFile(source.FullName, string.Empty);
                zip.Save();
            }

            using (var zip = new ZipFile(target.FullName))
                zip.ExtractAll(folder.FullName);
        }
    }
}

投掷:

Unhandled Exception: Ionic.Zip.BadReadException: bad read of entry AjaxControlToolkit.dll from compressed archive.
   at Ionic.Zip.ZipEntry._CheckRead(Int32 nbytes)
   at Ionic.Zip.ZipEntry.ExtractOne(Stream output)
   at Ionic.Zip.ZipEntry.InternalExtract(String baseDir, Stream outstream, String password)
   at Ionic.Zip.ZipFile._InternalExtractAll(String path, Boolean overrideExtractExistingProperty)
   at Ionic.Zip.ZipFile.ExtractAll(String path)
   at ConsoleApplication1.Program.Main(String[] args) in C:\ZipDemo\ConsoleApplication1\ConsoleApplication1\Program.cs:line 27

编辑:

如果我添加一个额外的字节,它就可以正常工作,但这不是一个可接受的解决方案。没有+ 1 会失败。

var bytes = new byte[source.Length + 1];
File.ReadAllBytes(source.FullName).CopyTo(bytes, 0);
zip.AddEntry(source.Name, bytes);

更新:

放弃并改用 SharpZipLib,因为它不会在简单提取时崩溃,但肯定会很高兴知道 DotNetZip 出了什么问题,它有更好的 API。

更新2:

关于文件长度的一些东西让它爆炸了,1179647 和 1179649 字节被正确压缩和解压缩。

var source = new FileInfo(@"C:\ZipDemo\foo.txt");
using (var writer = source.CreateText())
    writer.Write(new string('a', 1179648));

【问题讨论】:

  • 如果你尝试用其他工具解压缩它会发生什么,比如 WinRar ?
  • @Tigran 只是得到各种错误,即使用内置的 Windows 提取器我得到 0x80004005 未指定的错误。
  • 在 System.IO.Compression 中尝试 .net 4.5 中的 ZipArchive,看看是否遇到同样的问题。这很可能是一个错误。

标签: c# dotnetzip


【解决方案1】:

您的 dll 大小为 53*128k (6954496/131072 = 53),DotNetZip 中有一个错误,您可以在此处阅读:https://dotnetzip.codeplex.com/workitem/14087。只需在您的代码中使用:

zip.ParallelDeflateThreshold = -1;

我对很多文件都有这个问题,现在它工作得很好;)

【讨论】:

  • 这也解决了 C#4.5 文件压缩方法中的相同问题 :)
  • 谢谢!这是简单的解决方案,对我来说足够了。在下面@laktak 建议的修复程序中编译可能是更好的选择,但可能没有必要,除非您真的需要优化并行放气。遗憾的是,官方代码仓库似乎自 2011 年以来一直处于非活动状态 - 不确定是否有更新更活跃的代码继续更新。
  • 似乎该链接不再将您直接带到此问题中引用的工作项。因此,如果您有兴趣查找工作项,可以单击链接,切换到“问题”选项卡,然后搜索“ZipFile.AddFile 失败,具体取决于文件大小”。在页面上。这个问题看起来像是工作项 14087。
【解决方案2】:

这是一个错误 - 您可以在 Zlib\ParallelDeflateOutputStream.cs 中修复它。

改变

} while (doAll && (_lastWritten != _latestCompressed));

} while (doAll && (_lastWritten != _lastFilled)); 

请参阅https://dotnetzip.codeplex.com/workitem/14087 了解更多信息。

【讨论】:

    【解决方案3】:

    我试过了 -

    • 安装最新版本的 DotNetZip
    • 运行您的代码。
    • 得到 BadReadException

    那么这个-

    • 安装旧版本 (1.9) 的 DotNetZip。 (Install-Package DotNetZip -Version 1.9)
    • 运行您的代码
    • 代码运行良好。

    我猜这可能是一个错误?

    【讨论】:

    • 看起来像,提交了一个错误dotnetzip.codeplex.com/workitem/16092 无法判断是否有其他类似的,似乎 CodePlex 本身很糟糕并且不显示工作项描述。
    • 酷。使用我可以开始工作的示例更新了您的错误,应该对任何故障排除有用。
    • 这不是解决方案!当你改变版本时,大小也在改变,所以你暂时看不到问题。但是下次更新,问题可能会再次出现!
    • @Xaruth,不确定我是否理解您的观点。我所做的只是添加一个文件来存档、提取并与原始文件进行比较。它抛出了一个异常。参考this issue 对这些行进行一些分析。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多