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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9985684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:03:40  来源:igfitidea点击:

How do I archive multiple files into a .zip file using scala?

scalazipfile

提问by Pico

Could anyone post a simple snippet that does this?

任何人都可以发布一个简单的片段来做到这一点吗?

Files are text files, so compression would be nice rather than just archive the files.

文件是文本文件,因此压缩会很好,而不仅仅是存档文件。

I have the filenames stored in an iterable.

我将文件名存储在可迭代对象中。

回答by Travis Brown

There's not currently any way to do this kind of thing from the standard Scala library, but it's pretty easy to use java.util.zip:

目前没有任何方法可以从标准 Scala 库中执行此类操作,但它非常易于使用java.util.zip

def zip(out: String, files: Iterable[String]) = {
  import java.io.{ BufferedInputStream, FileInputStream, FileOutputStream }
  import java.util.zip.{ ZipEntry, ZipOutputStream }

  val zip = new ZipOutputStream(new FileOutputStream(out))

  files.foreach { name =>
    zip.putNextEntry(new ZipEntry(name))
    val in = new BufferedInputStream(new FileInputStream(name))
    var b = in.read()
    while (b > -1) {
      zip.write(b)
      b = in.read()
    }
    in.close()
    zip.closeEntry()
  }
  zip.close()
}

I'm focusing on simplicity instead of efficiency here (no error checking and reading and writing one byte at a time isn't ideal), but it works, and can very easily be improved.

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

回答by Gabriele Petronella

I recently had to work with zip files too and found this very nice utility: https://github.com/zeroturnaround/zt-zip

我最近也不得不使用 zip 文件,发现这个非常好的实用程序:https: //github.com/zeroturnaround/zt-zip

Here's an example of zipping all files inside a directory:

这是压缩目录中所有文件的示例:

import org.zeroturnaround.zip.ZipUtil
ZipUtil.pack(new File("/tmp/demo"), new File("/tmp/demo.zip"))

Very convenient.

很方便。

回答by George Pligoropoulos

This is a little bit more scala style in case you like functional:

如果您喜欢功能性,这是更多的 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()
    }
  }

and don't forget the imports:

并且不要忘记进口:

import java.io.{BufferedReader, FileOutputStream, File}
import java.util.zip.{ZipEntry, ZipOutputStream}
import io.Source

回答by camikiller

The Travis answer is correct but I have tweaked a little to get a faster version of his code:

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()
}

回答by mnp

A bit modified (shorter) version using NIO2:

使用 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()
}

回答by Dinesh Shinkar

As suggested by Gabriele Petronella, in addition need to add below maven dependency in pom.xml as well and below imports

正如 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>*