Return JGits git.archive() OutputStream 作为枚举器

Return JGits git.archive() OutputStream as Enumerator

我是 Scala 的新手,我想做的是通过 JGit 压缩 git 存储库并提供压缩文件作为下载。 这个想法是不会预先生成 Zip 文件,而是会即时压缩并立即传输。我已经让它在不使用 Jgit 和类似这个例子的情况下工作 https://gist.github.com/gre/4058734

但是,由于已经有一个 git.archive 方法可以将压缩存储库写入 OutputStream,我想使用它来代替上面的解决方案。 我尝试了以下方法,但没有用,而且我似乎无法找出原因。

  ArchiveFormats.registerAll();

  var enum = Enumerator.outputStream { os =>   
    git.archive()
      .setTree(git.getRepository.resolve("master"))
      .setFormat("zip")
      .setOutputStream(os)
      .call() 
   }

  ArchiveFormats.unregisterAll();


 Ok.stream(enum >>> Enumerator.eof).withHeaders(
 "Content-Type"->"application/zip", 
 "Content-Disposition"->"attachment; filename=asdf.zip"
)

问题在于 setOutputStream 期待 ByteArrayOutputStream,而不仅仅是 outputStream

您可以将 zip 内容放入 ByteArrayOutputStream,然后将其转换为 InputStream,这样您就可以 return 内容。

  ByteArrayOutputStream data= new ByteArrayOutputStream();

  git.archive()
      .setTree(git.getRepository.resolve("master"))
      .setFormat("zip")
      .setOutputStream(data)
      .call() 

  InputStream inStream = new ByteArrayInputStream(data.toByteArray());

  val dataContent: Enumerator[Array[Byte]] = Enumerator.fromStream(inStream)

  Ok.stream(dataContent).withHeaders(
     "Content-Type"->"application/zip", 
     "Content-Disposition"->"attachment; filename=asdf.zip"
  )

这里有一些注意事项需要注意,上面的示例显示了如何解决问题中的问题,但需要注意正在完成多少内存工作。

文档 here 涵盖了以块的形式发送大量数据的示例。

有一些注释 here 关于如何更有效地将 ByteArrayOutputStream 转换为 ByteArrayInputStream 如果您正在寻找最大效率。