使用Java在zip存档中提取文件时出错

时间:2012-08-13 19:17:32

标签: java zip

我正在使用此代码从zip存档中提取文件(省略所有catch语句和其他初始化语句):

zipInputStream = new ZipInputStream(new FileInputStream(file));
zipFile = new ZipFile(file);
for (Enumeration<?> em = zipFile.entries(); em.hasMoreElements();) {
    String extractedFileName = em.nextElement().toString();
    ZipEntry outerZipEntry = zipInputStream.getNextEntry();
    if (outerZipEntry.getName().contains(searchString)) {
        extractedFile = new File(outputDir + outerZipEntry.getName());
        out = new FileOutputStream(outputDir + extractedFileName);
        byte[] buf = new byte[1024];
        int len;
        while ((len = zipInputStream.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        break;
     } 
}

这个代码在提取文件时工作正常,例如/archive.zip/file_i_need.txt。

但是当我尝试从/archive.zip/folder1/file_i_need.txt中提取文件时,当我尝试使用readLine()读取文件时,我得到一个异常java.lang.NullPointerException: p>

String line = null ;
BufferedReader input = new BufferedReader(newFileReader(extractedFile)) ;
while( (line = input.readLine() ) != null ) {
    ...
}

我已经在两种情况下对它进行了测试,看起来这个代码在文件夹在文件夹中时不起作用,因为extractFileName是'folder / file_i_need.txt'而不是'file_i_need.txt'。

您可以推荐哪些建议?

谢谢!

3 个答案:

答案 0 :(得分:1)

我认为您的问题是您无法在out = new FileOutputStream(outputDir + extractedFileName);行上打开FileOutputStream。您无法打开流,因为如果extractedFileNamefolder1/file_i_need.txt而outputDir为C:/OutputDir,那么您正尝试在C:/OutputDirfolder1/file_i_need.txt上打开一个流。此目录不存在,out变为null。 我在评论中提到的帖子确实有一个解压缩操作,你可以在zip文件中看到目录条目的特殊处理。

答案 1 :(得分:1)

extractedFile = new File(outputDir + outerZipEntry.getName());

问题是您没有考虑条目名称可能包含您未创建的路径元素,您只需尝试写入该文件。为什么这不会产生错误,我不确定。

你在Windows上写这些文件吗?这将在文件系统上创建类似folder1/file_i_need.txt的文件,在某种程度上可能无效:P

尝试从ZipEntry

中提取文件名
String name = outerZipEntry.getName();
name = name.substring(name.lastIndexOf("/") + 1);

显然,检查名称实际上是否包含“/”;)

<强>更新

虽然我在这,但看起来不对

extractedFile = new File(outputDir + outerZipEntry.getName());
out = new FileOutputStream(outputDir + extractedFileName);

基本上就是你的outputDir + outerZipEntry.getName() + (outputDir + outerZipEntry.getName())

<强>更新

我在Windows上对此进行了测试,当我尝试将文件写入不存在的路径时,我得到FileNotFoundException

我也在我的MaC上测试了它,我得到了FileNotFoundException

我不知道你的错误处理是做什么的,但它做错了。

答案 2 :(得分:0)

您正在以两种不同的方式迭代zip条目:

迭代1:

for (Enumeration<?> em = zipFile.entries(); em.hasMoreElements();) {

迭代2:

ZipEntry outerZipEntry = zipInputStream.getNextEntry();

做一个或另一个。使用ZipFile API或ZipInputStream API。我强烈怀疑这是NullPointerException的来源。