使用 java.util.zip 类写入 zip 文件时的一个 Bug






4.58/5 (15投票s)
描述了使用 java.util.zip 类将二进制文件写入 zip 文件时出现的问题
引言
我正在用 C# 编写一个小型的 .NET 应用程序,并寻找一个可以让我读取和写入 zip 文件的库。这时,我的第一次 Google 搜索给了我一个链接到 使用 J# 类库中的 Zip 类来压缩文件和数据 (C#)。太棒了! - 这是我最初的反应,但并没有持续多久。你可以读取 zip 文件,但是当你写入 zip 文件时,如果你有二进制文件(正如你通常会遇到的情况),生成的 zip 文件将会损坏,你无法将其读回。有趣的是,WinZip 可以打开它(忽略头部错误),而一位微软人员在 MS 新闻组中提出的建议是使用 WinZip 提取所有文件,然后重新压缩。 哈哈。如果他们可以选择将 WinZip 纳入其中,为什么还要使用压缩库呢?
甚至没有关于这个 bug 的 KB 文章 - 太糟糕了!我使用这些类时浪费了大约半天的时间,因为我最初认为问题出在我的代码中。无论如何,这是一个警告。如果你使用的是 BCL 1.1 版本,请不要使用 J# 类库进行压缩/解压缩。 Heath Stewart (C# MVP 和 CodeProject 编辑) 告诉我 BCL 2.0 包含压缩功能 - 这真是个好消息。而且在发布之前,一个非常好的 J# 类库的免费替代品是 SharpZipLib,我强烈推荐它。
Bug 演示
- 创建一个新的 C# 控制台应用程序项目
- 添加对 vjslib 的引用(...Microsoft.NET\Framework\v1.1.4322\vjslib.dll)
- 将以下代码复制/粘贴到你的主 cs 文件中 :-
using System; using System.IO; using java.util.zip; class MainClass { [STAThread] static void Main(string[] args) { BugDemo(); } static void BugDemo() { //Write zip file ZipOutputStream os = new ZipOutputStream( new java.io.FileOutputStream("test.zip")); ZipEntry ze = new ZipEntry("gluk.gif"); ze.setMethod(ZipEntry.DEFLATED); os.putNextEntry(ze); java.io.FileInputStream fs = new java.io.FileInputStream("gluk.gif"); sbyte[] buff = new sbyte[1024]; int n = 0; while ((n=fs.read(buff,0,buff.Length))>0) { os.write(buff,0,n); } fs.close(); os.closeEntry(); os.close(); Console.WriteLine("Okay, the zip has been written."); //Read zip file try { //Bug will occur here ZipFile zf = new ZipFile("test.zip"); } catch { Console.WriteLine("Bug confirmed!"); } } }
-
现在确保在与可执行文件相同的文件夹中有一个 gluk.gif 文件。
-
编译并运行。
解决方法
这个问题没有真正的解决方法。你可以使用我上面提到的替代库,或者等待 Whidbey 的发布。