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が、要素を取り出そうとするとnullポインタが発生します。

例外は、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 ezc、またはbnamewerenullです。

enullこのメソッドで明確にインスタンス化されているため、することはできません。

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

つまり、デバッグがかなり難しくなるはずですbname。メソッドです:nullgetEntryBytesnative

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

これが私が進める方法です:

  • それが特定の zip ファイルなのか、すべての zip ファイルなのかを判断します。その特定の zip ファイルの場合は、再作成してみてください。
  • Java のバージョンを更新してください。バグが修正された可能性がありますgetEntryBytes
  • オラクルにバグレポートを提出する
于 2013-02-21T02:56:23.883 に答える
0

最近同じ問題が発生したため、JDK1.61.7に関連するzipソースコードを比較しました。

本当の理由は、 jd​​k1.6が次のようなコンストラクターによってjzentryzipEntryを初期化することです。

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 に答える