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

后端 未结 6 1056
孤独总比滥情好
孤独总比滥情好 2020-12-14 19:41

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 filename

相关标签:
6条回答
  • 2020-12-14 19:41

    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:

    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.

    0 讨论(0)
  • 2020-12-14 19:45

    I recently had to work with zip files too and found this very nice utility: 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.

    0 讨论(0)
  • 2020-12-14 19:54

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

      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
    
    0 讨论(0)
  • 2020-12-14 19:56

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

    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()
    }
    
    0 讨论(0)
  • 2020-12-14 19:58

    A bit modified (shorter) version using 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()
    }
    
    0 讨论(0)
  • 2020-12-14 19:59

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

    *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>*
    
    0 讨论(0)
提交回复
热议问题