4

我在java中提取一个ZIP文件:

ZipFile zipFile = new ZipFile(theZipFile);
  Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
    while(zipEntries.hasMoreElements()){
      ZipEntry entry = zipEntries.nextElement(); /// <---Nullpointer exception happens here
  }

代码执行过去 while(zipEntries.hasMoreElements())但未能提取 ZipEntry。

返回true很奇怪hasMoreElements,但是尝试取出元素时会出现空指针。

JDK lib 的 ZipFile 类中出现异常,我在调试器中看不到局部变量,那么如何找出 Zip 文件有什么问题?

编辑:堆栈跟踪:

java.lang.NullPointerException
    at java.util.zip.ZipFile.getZipEntry(ZipFile.java:529)
    at java.util.zip.ZipFile.access$900(ZipFile.java:56)
    at java.util.zip.ZipFile$1.nextElement(ZipFile.java:511)
    at java.util.zip.ZipFile$1.nextElement(ZipFile.java:481)
4

2 回答 2

3

这是getZipEntry方法(截至 1.7.0_10):

private ZipEntry getZipEntry(String name, long jzentry) {
    ZipEntry e = new ZipEntry();
    e.flag = getEntryFlag(jzentry);  // get the flag first
    if (name != null) {
        e.name = name;
    } else {
        byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
        if (!zc.isUTF8() && (e.flag & EFS) != 0) {
            e.name = zc.toStringUTF8(bname, bname.length);
        } else {
            e.name = zc.toString(bname, bname.length);      // Line 529
        }
    }
    /* snip */
    return e;
}

NullPointerException在这条线上抛出a 的唯一原因是 if ezcbnamewere null

e不可能,null因为它在这个方法中被明确地实例化了。

zc不能null

public ZipFile(File file, int mode, Charset charset) throws IOException
{
    /* snip */
    this.zc = ZipCoder.get(charset);
    /* snip */
}

static ZipCoder get(Charset charset) {
    return new ZipCoder(charset);
}

这意味着bnamemust be null,这将很难调试。getEntryBytes是一种native方法:

private static native byte[] getEntryBytes(long jzentry, int type);

这就是我将如何进行:

  • 弄清楚它是那个特定的 zip 文件还是所有的 zip 文件。如果是那个特定的 zip 文件,请尝试重新制作它。
  • 更新您的 Java 版本,可能存在已修复的getEntryBytes错误
  • 向 Oracle 提交错误报告
于 2013-02-21T02:56:23.883 回答
0

我最近遇到了同样的问题,所以我比较了JDK 1.61.7相关的zip 源代码

真正的原因jdk 1.6将通过构造函数使用jzentry初始化zipEntry ,如下所示:

ZipEntry ze = new ZipEntry(jzentry);

ZipEntry(long jzentry) {
    initFields(jzentry);
}

但在jdk 1.7我们可以看到它使用

private ZipEntry getZipEntry(String name, long jzentry) {
    ZipEntry e = new ZipEntry(); // it did not use jzentry initial it

当某些jar文件有空条目时,它会抛出异常。

于 2013-03-18T06:06:40.993 回答