Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用scala将多个文件归档到.zip文件中?_Scala_Zipfile - Fatal编程技术网

如何使用scala将多个文件归档到.zip文件中?

如何使用scala将多个文件归档到.zip文件中?,scala,zipfile,Scala,Zipfile,有人能发布一个简单的代码片段来实现这一点吗 文件是文本文件,因此压缩比归档文件更好 我将文件名存储在一个iterable中。目前还没有从标准Scala库中执行此类操作的方法,但它非常易于使用: 在这里,我关注的是简单性而不是效率(没有错误检查,一次读写一个字节并不理想),但它可以工作,并且可以很容易地改进。如果您喜欢函数式,这是一种更具scala风格的风格: def compress(zipFilepath: String, files: List[File]) { def read

有人能发布一个简单的代码片段来实现这一点吗

文件是文本文件,因此压缩比归档文件更好


我将文件名存储在一个iterable中。

目前还没有从标准Scala库中执行此类操作的方法,但它非常易于使用:


在这里,我关注的是简单性而不是效率(没有错误检查,一次读写一个字节并不理想),但它可以工作,并且可以很容易地改进。

如果您喜欢函数式,这是一种更具scala风格的风格:

  def compress(zipFilepath: String, files: List[File]) {
    def readByte(bufferedReader: BufferedReader): Stream[Int] = {
      bufferedReader.read() #:: readByte(bufferedReader)
    }
    val zip = new ZipOutputStream(new FileOutputStream(zipFilepath))
    try {
      for (file <- files) {
        //add zip entry to output stream
        zip.putNextEntry(new ZipEntry(file.getName))

        val in = Source.fromFile(file.getCanonicalPath).bufferedReader()
        try {
          readByte(in).takeWhile(_ > -1).toList.foreach(zip.write(_))
        }
        finally {
          in.close()
        }

        zip.closeEntry()
      }
    }
    finally {
      zip.close()
    }
  }

Travis的答案是正确的,但我已经做了一些调整,以获得他的代码的更快版本:

val Buffer = 2 * 1024

def zip(out: String, files: Iterable[String], retainPathInfo: Boolean = true) = {
  var data = new Array[Byte](Buffer)
  val zip = new ZipOutputStream(new FileOutputStream(out))
  files.foreach { name =>
    if (!retainPathInfo)
      zip.putNextEntry(new ZipEntry(name.splitAt(name.lastIndexOf(File.separatorChar) + 1)._2))
    else
      zip.putNextEntry(new ZipEntry(name))
    val in = new BufferedInputStream(new FileInputStream(name), Buffer)
    var b = in.read(data, 0, Buffer)
    while (b != -1) {
      zip.write(data, 0, b)
      b = in.read(data, 0, Buffer)
    }
    in.close()
    zip.closeEntry()
  }
  zip.close()
}

我最近也不得不使用zip文件,并发现这个非常好的实用程序:

下面是一个压缩目录中所有文件的示例:

import org.zeroturnaround.zip.ZipUtil
ZipUtil.pack(new File("/tmp/demo"), new File("/tmp/demo.zip"))
非常方便。

使用NIO2稍微修改(更短)的版本:

private def zip(out: Path, files: Iterable[Path]) = {
  val zip = new ZipOutputStream(Files.newOutputStream(out))

  files.foreach { file =>
    zip.putNextEntry(new ZipEntry(file.toString))
    Files.copy(file, zip)
    zip.closeEntry()
  }
  zip.close()
}

正如Gabriele Petronella所建议的,此外,还需要在pom.xml中添加以下maven依赖项以及以下导入

*import org.zeroturnaround.zip.ZipUtil
import java.io.File
<dependency>
    <groupId>org.zeroturnaround</groupId>
    <artifactId>zt-zip</artifactId>
    <version>1.13</version>
    <type>jar</type>
</dependency>*
*导入org.zeroturnal.zip.ZipUtil
导入java.io.xml文件
零周转
zt拉链
1.13
罐子
*

我知道它没有经过优化,但没有必要将字节包装到数组中。您可以简单地
zip.write(b)
。此外,不要忘记在
中关闭
,并在
中关闭
zip
,最后从sbtwile-loop alternative
Stream.in.read()).takeWhile(>-1)。foreach{b=>zip.write(b)}
readByte(in).takeWhile(>-1).toList
将在读取大文件时消耗大量内存。使用迭代器可能更好。
def readByte(bufferedReader:bufferedReader)=Stream.continuously(bufferedReader.read())
private def zip(out: Path, files: Iterable[Path]) = {
  val zip = new ZipOutputStream(Files.newOutputStream(out))

  files.foreach { file =>
    zip.putNextEntry(new ZipEntry(file.toString))
    Files.copy(file, zip)
    zip.closeEntry()
  }
  zip.close()
}
*import org.zeroturnaround.zip.ZipUtil
import java.io.File
<dependency>
    <groupId>org.zeroturnaround</groupId>
    <artifactId>zt-zip</artifactId>
    <version>1.13</version>
    <type>jar</type>
</dependency>*