如何解压zip文件使用scala?

基本上我需要解压缩一个.zip文件,其中包含一个名为modeled的文件夹,该文件夹又包含一些excel文件。

我find了一些已经写好的代码(zipArchive),这个代码是为了解压缩zip文件,但是我不知道为什么当我使用它的时候会抛出一个错误信息。 下面列出了ZipArchive的代码和错误消息:

import java.io.{OutputStream, InputStream, File, FileOutputStream} import java.util.zip.{ZipEntry, ZipFile} import scala.collection.JavaConversions._ object ZipArchive { val BUFSIZE = 4096 val buffer = new Array[Byte](BUFSIZE) def unZip(source: String, targetFolder: String) = { val zipFile = new ZipFile(source) unzipAllFile(zipFile.entries.toList, getZipEntryInputStream(zipFile)_, new File(targetFolder)) } def getZipEntryInputStream(zipFile: ZipFile)(entry: ZipEntry) = zipFile.getInputStream(entry) def unzipAllFile(entryList: List[ZipEntry], inputGetter: (ZipEntry) => InputStream, targetFolder: File): Boolean = { entryList match { case entry :: entries => if (entry.isDirectory) new File(targetFolder, entry.getName).mkdirs else saveFile(inputGetter(entry), new FileOutputStream(new File(targetFolder, entry.getName))) unzipAllFile(entries, inputGetter, targetFolder) case _ => true } } def saveFile(fis: InputStream, fos: OutputStream) = { writeToFile(bufferReader(fis)_, fos) fis.close fos.close } def bufferReader(fis: InputStream)(buffer: Array[Byte]) = (fis.read(buffer), buffer) def writeToFile(reader: (Array[Byte]) => Tuple2[Int, Array[Byte]], fos: OutputStream): Boolean = { val (length, data) = reader(buffer) if (length >= 0) { fos.write(data, 0, length) writeToFile(reader, fos) } else true } } 

错误信息:

 java.io.FileNotFoundException: src/test/resources/oepTemp/modeled/EQ_US_2_NULL_('CA')_ALL_ELT_IL_EQ_US.xlsx (No such file or directory), took 6.406 sec [error] at java.io.FileOutputStream.open(Native Method) [error] at java.io.FileOutputStream.<init>(FileOutputStream.java:221) [error] at java.io.FileOutputStream.<init>(FileOutputStream.java:171) [error] at com.contract.testing.ZipArchive$.unzipAllFile(ZipArchive.scala:28) [error] at com.contract.testing.ZipArchive$.unZip(ZipArchive.scala:15) [error] at com.contract.testing.OepStepDefinitions$$anonfun$1.apply$mcZ$sp(OepStepDefinitions.scala:175) [error] at com.contract.testing.OepStepDefinitions$$anonfun$1.apply(OepStepDefinitions.scala:150) [error] at com.contract.testing.OepStepDefinitions$$anonfun$1.apply(OepStepDefinitions.scala:150) [error] at cucumber.api.scala.ScalaDsl$StepBody$$anonfun$apply$1.applyOrElse(ScalaDsl.scala:61) [error] at cucumber.api.scala.ScalaDsl$StepBody$$anonfun$apply$1.applyOrElse(ScalaDsl.scala:61) [error] at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) [error] at cucumber.runtime.scala.ScalaStepDefinition.execute(ScalaStepDefinition.scala:71) [error] at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37) [error] at cucumber.runtime.Runtime.runStep(Runtime.java:298) [error] at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44) [error] at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39) [error] at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:48) [error] at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:91) [error] at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63) [error] at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18) [error] ... 

所以根据错误消息,它看起来像试图find导出的Excel文件? 这部分完全抛弃了我。 任何帮助将不胜感激。 我在下面添加了如何调用方法,也许我正在做一些愚蠢的事情。 如果你能推荐一个zip文件,我也可以使用不同的方法来提取我的zip文件。

 val tempDirectoryDir = "src/test/resources/oepTemp/" ZipArchive.unZip(tempDirectoryDir + "Sub Region Input - Output.zip", tempDirectoryDir) 

那么因为正在使用一些来自java的实用程序,这里是一个基于此的版本,翻译成scala,也许这应该是更多的function,但它是有用的

 package zip import java.io.{ IOException, FileOutputStream, FileInputStream, File } import java.util.zip.{ ZipEntry, ZipInputStream } /** * Created by anquegi on 04/06/15. */ object Unzip extends App { val INPUT_ZIP_FILE: String = "src/main/resources/my-zip.zip"; val OUTPUT_FOLDER: String = "src/main/resources/my-zip"; def unZipIt(zipFile: String, outputFolder: String): Unit = { val buffer = new Array[Byte](1024) try { //output directory val folder = new File(OUTPUT_FOLDER); if (!folder.exists()) { folder.mkdir(); } //zip file content val zis: ZipInputStream = new ZipInputStream(new FileInputStream(zipFile)); //get the zipped file list entry var ze: ZipEntry = zis.getNextEntry(); while (ze != null) { val fileName = ze.getName(); val newFile = new File(outputFolder + File.separator + fileName); System.out.println("file unzip : " + newFile.getAbsoluteFile()); //create folders new File(newFile.getParent()).mkdirs(); val fos = new FileOutputStream(newFile); var len: Int = zis.read(buffer); while (len > 0) { fos.write(buffer, 0, len) len = zis.read(buffer) } fos.close() ze = zis.getNextEntry() } zis.closeEntry() zis.close() } catch { case e: IOException => println("exception caught: " + e.getMessage) } } Unzip.unZipIt(INPUT_ZIP_FILE, OUTPUT_FOLDER) } 

这是一个更实用,更精确的方法

 import java.io.{FileInputStream, FileOutputStream} import java.util.zip.ZipInputStream val fis = new FileInputStream("htl.zip") val zis = new ZipInputStream(fis) Stream.continually(zis.getNextEntry).takeWhile(_ != null).foreach{ file => val fout = new FileOutputStream(file.getName) val buffer = new Array[Byte](1024) Stream.continually(zis.read(buffer)).takeWhile(_ != -1).foreach(fout.write(buffer, 0, _)) } 

试着和天亮的解决scheme一起工作,我意识到它不适用于具有目录结构的zip。 所以我采用这种方式:

  import java.io.{FileOutputStream, InputStream} import java.nio.file.Path import java.util.zip.ZipInputStream def unzip(zipFile: InputStream, destination: Path): Unit = { val zis = new ZipInputStream(zipFile) Stream.continually(zis.getNextEntry).takeWhile(_ != null).foreach { file => if (!file.isDirectory) { val outPath = destination.resolve(file.getName) val outPathParent = outPath.getParent if (!outPathParent.toFile.exists()) { outPathParent.toFile.mkdirs() } val outFile = outPath.toFile val out = new FileOutputStream(outFile) val buffer = new Array[Byte](4096) Stream.continually(zis.read(buffer)).takeWhile(_ != -1).foreach(out.write(buffer, 0, _)) } } } 
 import java.io.FileInputStream import java.io.InputStream import java.util.zip.ZipEntry import java.util.zip.ZipInputStream import scala.language.reflectiveCalls import scala.util.Try import org.apache.commons.io.IOUtils def using[T <: { def close() }, U](resource: T)(block: T => U): U = { try { block(resource) } finally { if (resource != null) { resource.close() } } } def processZipFile(zipFile: ZipFile)(doStuff: ZipEntry => Unit) { using(new ZipInputStream(new FileInputStream(zipFile))) { zipInputStream => val entries = Stream.continually(Try(zipInputStream.getNextEntry()).getOrElse(null)) .takeWhile(_ != null) // while not EOF and not corrupted .foreach(doStuff) .force } }