当前位置: 首页 > 知识库问答 >
问题:

如何在Scala中通过Play Framework 2.5流压缩文件(动态)?

齐朝明
2023-03-14

我正在研究这个实现:https://gist.github.com/kirked/03c7f111de0e9a1f74377bf95d3f0f60,但不知道如何使用它。

 import java.io.{BufferedOutputStream, ByteArrayInputStream, ByteArrayOutputStream}
import java.util.zip.{ZipEntry, ZipOutputStream}
import akka.stream.scaladsl.{StreamConverters}
import org.apache.commons.io.FileUtils
import play.api.mvc.{Action, Controller}

class HomeController extends Controller {
  def single() = Action {
                         Ok.sendFile(
                           content = new java.io.File("C:\\Users\\a.csv"),
                           fileName = _ => "a.csv"
                         )
                       }

  def zip() = Action {
                     Ok.chunked(StreamConverters.fromInputStream(fileByteData)).withHeaders(
                       CONTENT_TYPE -> "application/zip",
                       CONTENT_DISPOSITION -> s"attachment; filename = test.zip"
                     )
                   }

  def fileByteData(): ByteArrayInputStream = {
    val fileList = List(
      new java.io.File("C:\\Users\\a.csv"),
      new java.io.File("C:\\Users\\b.csv")
    )

    val baos = new ByteArrayOutputStream()
    val zos = new ZipOutputStream(new BufferedOutputStream(baos))

    try {
      fileList.map(file => {
        zos.putNextEntry(new ZipEntry(file.toPath.getFileName.toString))
        zos.write(FileUtils.readFileToByteArray(file))
        zos.closeEntry()
      })
    } finally {
      zos.close()
    }

    new ByteArrayInputStream(baos.toByteArray)
  }
}

共有1个答案

花博厚
2023-03-14

您可以使用Java的管道机制,而不是使用ByteArrayOutputStream缓冲数组中的内容,然后将它们放入ByteArrayInputStream中。

这里有一个草图解决方案:

def zip() = Action {
  // Create Source that listens to an OutputStream
  // and pass it to `fileByteData` method.
  val zipSource: Source[ByteString, Unit] =
    StreamConverters
      .asOutputStream()
      .mapMaterializedValue(fileByteData)
  Ok.chunked(zipSource).withHeaders(
    CONTENT_TYPE -> "application/zip",
    CONTENT_DISPOSITION -> s"attachment; filename = test.zip")
}

// Send the file data, given an OutputStream to write to.
def fileByteData(os: OutputStream): Unit = {
  val fileList = List(
    new java.io.File("C:\\Users\\a.csv"),
    new java.io.File("C:\\Users\\b.csv")
  )

  val zos = new ZipOutputStream(os)
  val buffer: Array[Byte] = new Array[Byte](2048)
  try {
    for (file <- fileList) {
      zos.putNextEntry(new ZipEntry(file.toPath.getFileName.toString))
      val fis = new Files.newInputStream(file.toPath)
      try {
        @tailrec
        def zipFile(): Unit = {
          val bytesRead = fis.read(buffer)
          if (bytesRead == -1) () else {
            zos.write(buffer, 0, bytesRead)
            zipFile()
          }
        }
        zipFile()
      } finally fis.close()
      zos.closeEntry()
    }
  } finally {
    zos.close()
  }
}

这只是一个方法的概要。您还需要确保:-线程运行正常-filebytedata有望在发送线程的另一个线程上运行-错误处理正常-例如,如果服务器(如找不到文件)或客户端(提前断开连接)出现错误,所有流将正确关闭

 类似资料:
  • 我正试图用Java编写一个程序来解压大型机中PKZIP工具压缩的文件。然而,我试过以下三种方法,它们都不能解决我的问题。 > by exe. 我试图通过WinRAR、7Zip和Linux命令(解压)打开它。全部失败,错误信息如下: 档案不是格式未知就是损坏了 通过jdkapi-java。util。拉链 正如这个网站所描述的,我还尝试用JDKAPI解压它。但是,它失败并显示错误消息: IO错误:ja

  • 问题内容: 任何人都可以向我展示在我一直在搜索的Java中压缩和解压缩tar.gzip文件的正确方法,但是我能找到的最多是zip或gzip(单独)。 问题答案: 我最喜欢的是plexus-archiver-请参阅GitHub上的资源。 另一个选项是Apache commons- compress- (请参阅mvnrepository)。 使用plexus-utils,用于取消存档的代码如下所示:

  • 我正在使用Julia的ZipFile包来提取和处理csv文件。没问题,但是当我遇到zip文件中的zip文件时,我也想处理它,但是遇到了一个错误。 Julia ZipFile文档如下:https://zipfilejl.readthedocs.io/en/latest/ 对如何做到这一点有什么想法吗?

  • 我对Spark和Scala是新手。我们将广告事件日志文件格式化为CSV,然后使用PKZIP进行压缩。我已经看到了许多关于如何使用Java解压缩压缩文件的示例,但是如何使用Scala for Spark来实现这一点呢?我们最终希望从每个传入文件中获取、提取并加载数据到Hbase目标表中。也许这可以用HadooprDD来完成吗?在这之后,我们将引入Spark streaming来监视这些文件。

  • 问题内容: 我正在使用此示例中的代码从发送一个到我的Web服务器。在这里复制代码 我的问题 如何在将其发送到服务器之前对其进行最佳压缩,以及如何在服务器(我正在使用)上对其进行解压缩? 问题答案: 根据此http://android-developers.blogspot.com/2011/09/androids-http- clients.html 如果您使用的是Gingerbread或更高版本

  • 问题内容: TL; DR; 上传之前,有没有一种方法可以直接在浏览器端压缩图像(主要是jpeg,png和gif)?我很确定JavaScript可以做到这一点,但是我找不到实现它的方法。 这是我要实现的完整方案: 用户访问我的网站,然后通过元素选择图片, 该图片是通过JavaScript检索的,我们进行了一些验证,例如正确的文件格式,最大文件大小等, 如果一切正常,则会在页面上显示图像的预览, 用户