2017-06-29 49 views
2

我想要做的是在nodeJs中创建一个zip文件,然后通过Java代码(一个已编写的Java程序来处理zip)提取它。无法通过nodeJs中的Java代码提取zip文件代码

我能够在nodeJs中使用jszip创建zip文件,但我的java代码无法提取该zip文件(虽然我的查找程序可以提取它,甚至我在nodeJs中的提取代码也可以)。

的NodeJS代码来创建ZIP:

this.zip = function (sourceDirectory, zipFile, excludParent) { 
     var zip = new JSZip(); 

     var list = getFiles(sourceDirectory, excludParent); 
     for (var i = 0; i < list.length; i++) { 
      var obj = list[i]; 
      if(typeof(obj.source) == "undefined"){ 
       if (excludParent) 
        zip.folder(obj.target.substring(obj.target.indexOf("/") + 1)); 
       else 
        zip.folder(obj.target); 
      }else { 
       if (excludParent) 
        zip.file(obj.target.substring(obj.target.indexOf("/") + 1), fs.readFileSync(obj.target), {base64: true}); 
       else 
        zip.file(obj.target, fs.readFileSync(obj.target), {base64: true}); 
      } 
     } 
     zip.generateNodeStream({type:'nodebuffer', streamFiles:true, compressionOptions:'DEFAULT'}) 
      .pipe(fs.createWriteStream(zipFile)) 
      .on('finish', function() { 
       console.log(zipFile + " written."); 
      }) 
    }; 

    var getFiles = function (sourceDirectory, excludeParent) { 
     var list = []; 
     if (excludeParent) { 
      if (fs.lstatSync(sourceDirectory).isDirectory()) { 
       var fileList = fs.readdirSync(sourceDirectory); 
       for (var i = 0; i < fileList.length; i++) { 
        list = list.concat(getFiles_(sourceDirectory + sep, fileList[i])); 
       } 
      } 
     } else { 
      list = getFiles_("", sourceDirectory); 
     } 
     return list; 
    }; 


    var getFiles_ = function (parentDir, path) { 
     var list = []; 

     if (path.indexOf(".") == 0) return list; 
     if (fs.lstatSync(parentDir + path).isDirectory()) { 
      list.push({target: parentDir + path}); 

      var fileList = fs.readdirSync(parentDir + path); 
      for (var i = 0; i < fileList.length; i++) { 
       list = list.concat(getFiles_(parentDir + path + sep, fileList[i])); 
      } 
     } else { 
      list.push({source: parentDir + path, target: parentDir + path}); 
     } 
     return list; 
    }; 

Java代码中提取文件:

public void unzip(String zipFilePath, String destDirectory) throws IOException { 
     File destDir = new File(destDirectory); 
     if (!destDir.exists()) { 
      destDir.mkdir(); 
     } 
     ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath)); 
     ZipEntry entry = zipIn.getNextEntry(); 
     // iterates over entries in the zip file 
     while (entry != null) { 
      String filePath = destDirectory + File.separator + entry.getName(); 
      if (!entry.isDirectory()) { 
       // if the entry is a file, extracts it 
       extractFile(zipIn, filePath); 
      } else { 
       // if the entry is a directory, make the directory 
       File dir = new File(filePath); 
       dir.mkdirs(); 
      } 
      zipIn.closeEntry(); 
      entry = zipIn.getNextEntry(); 
     } 
     zipIn.close(); 
    } 

此代码抛出下面的堆栈跟踪:

java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor 
    at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:310) 
    at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:122) 
    at module.builder.ZipUtility.unzip(ZipUtility.java:57) 
    at module.builder.DataPatcher.unZipAndroidImageFiles(DataPatcher.java:624) 
    at module.builder.DataPatcher.patchAndroid(DataPatcher.java:145) 
    at module.builder.FXMLDocumentController$5.call(FXMLDocumentController.java:324) 
    at module.builder.FXMLDocumentController$5.call(FXMLDocumentController.java:312) 
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.lang.Thread.run(Thread.java:745) 

这段Java代码,如果我工作正常通过应用程序创建一个zip文件(即winzip,winrar,拉链制成b y finder等),但它会抛出ava.util.zip.ZipException: only DEFLATED entries can have EXT descriptor,同时通过上述nodeJs方法提取zip。

+0

你可以尝试使用[Apache Commons Compress](https://commons.apache.org/proper/commons-compress/zip.html)或者至少阅读链接页面上的文档,这应该解释一些事情。其一是数据描述符只在使用压缩条目时才能可靠工作,并且我猜jszip总是写它们。也许你可以改变你在nodejs代码中传递的'compressionOptions'来只使用压缩条目。 – Thomas

回答

1

今天我遇到了同样的问题。

问题在于streamFiles:true作为选项传递给zip.generateNodeStream()。从the docs

当此选项为true时,我们将流传输文件并在条目末尾使用数据描述符。此选项使用较少的内存,但某些程序可能不支持数据描述符(并且不会接受生成的zip文件)。

只要您不担心内存使用情况,删除streamFiles:true选项应该可以工作。