【问题标题】:How do I archive multiple files into a .zip file using scala?如何使用 scala 将多个文件归档到 .zip 文件中?
【发布时间】:2012-04-16 15:49:56
【问题描述】:

谁能发布一个简单的sn-p来做到这一点?

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

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

【问题讨论】:

    标签: scala zipfile


    【解决方案1】:

    目前没有任何方法可以从标准 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()
    }
    

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

    【讨论】:

    • 而且我知道它没有经过优化,但没有必要将字节包装在数组中。你可以简单地zip.write(b)
    • 另外,不要忘记在finally 块中关闭inzip
    • sbt.IO.zip() 来自 sbt
    • while循环替代Stream.continually(in.read()).takeWhile(_ > -1).foreach { b => zip.write(b) }
    【解决方案2】:

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

    这是一个将所有文件压缩到目录中的示例:

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

    非常方便。

    【讨论】:

      【解决方案3】:

      如果你喜欢功能性,这有点 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()
          }
        }
      

      别忘了导入:

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

      【讨论】:

      • readByte(in).takeWhile(_ &gt; -1).toList 在读取大文件时会消耗大量内存。使用Iterator 可能会更好。
      • def readByte(bufferedReader: BufferedReader) = Stream.continually(bufferedReader.read())
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          根据 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>*
          

          【讨论】:

            猜你喜欢
            • 2012-08-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-02
            • 1970-01-01
            • 2016-12-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多