我在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时失败。
奇怪的是hasMoreElements
返回true,但在尝试获取元素时会出现空指针。
异常来自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)
答案 0 :(得分:3)
以下是getZipEntry
方法(截至2010年10月1日):
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
,e
或zc
bname
为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);
}
:
bname
这意味着null
必须是getEntryBytes
,这将非常难以调试。 native
是private static native byte[] getEntryBytes(long jzentry, int type);
方法:
getEntryBytes
这就是我要继续下去的方式:
答案 1 :(得分:0)
我最近遇到了同样的问题,因此我比较了 JDK 1.6 和 1.7 相关的 zip源代码。
真正的原因 jdk 1.6 将 jentry 初始 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 文件有空条目时,它会抛出异常。