scala - 如何在 Play 2.1 中使用带有分块响应的 OutputStreams

标签 scala playframework outputstream iterate

我需要使用到 java.util.zip.ZipOutputStream以压缩文件存档响应。

未压缩的数据有几百兆字节,所以我想尽可能少地存储它。它来自 SQL 结果的序列化。

我看到使用 OutputStream 的示例使用 Enumerator.outputStream 返回分块结果:

  • http://greweb.me/2012/11/play-framework-enumerator-outputstream/
  • Play/Akka integration with Java OutputStreams

  • 但是当我阅读文档时,这些似乎是不明智的(强调我的)

    Create an Enumerator of bytes with an OutputStream.

    Not that calls to write will not block, so if the iteratee that is being fed to is slow to consume the input, the OutputStream will not push back. This means it should not be used with large streams since there is a risk of running out of memory.



    显然,我不能使用那个。或者至少不是没有修改。

    如何使用 OutputStream 创建响应(在这种情况下,一个 gzip 压缩的存档)同时确保只有部分内容会存储在内存中?

    我承认 InputStream 之间的区别s/OutputStream s and Play的Enumerator/Iteratee范式,所以我希望会有一种特定的方式来生成我的源数据(SQL 结果的序列化),这样它就不会超过下载速度。我不知道它是什么。

    最佳答案

    一般来说,您不能安全地使用任何 OutputStream使用 Enumerator/Iteratee 框架,因为 OutputStream不支持非阻塞回推。但是,如果您可以控制写入 OutputStream你可以一起破解类似的东西:

    val baos = new ByteArrayOutputStream
    val zos = new ZipOutputStream(baos)
    
    val enumerator = Enumerator.generateM {
      Future.successful {
        if (moreDateToWrite) {
          // Write data into zos
          val r = Some(baos.toByteArray)
          baos.reset()
          r
        } else None
      }
    }
    

    如果您只需要压缩,请查看 Enumeratee play.filters.gzip.Gzip 中提供的实例和 play.filters.gzip.GzipFilter筛选。

    关于scala - 如何在 Play 2.1 中使用带有分块响应的 OutputStreams,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24718645/

    相关文章:

    java - Play Framework 2 : Read the application version defined in Build. scala

    java - 存储应用程序 transient 配置的推荐做法

    Java OutputStream.write() 抛出错误的文件描述符,但刷新有效

    scala - Scala 中的模式匹配元组

    scala - Scalamock无法区分 future

    playframework - 类型安全激活器可用的命令行选项/功能

    PHP:关闭输出流

    linux - 在文件中运行时,BLKID 在 Linux 中不提供输出

    scala - 在 Scala 编译器处理的特征中,final val 是如何定义的?

    java - 斯卡拉性能 : Why is this Scala app 30x slower than the equivalent Java app?