如何使用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 alternativeStream.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>*