我尝试使用akka流(scala)来读取从Play的WS客户端流式传输的gzip压缩数据。数据最终需要作为传统API的InputStream呈现。我使用的是akka 2.4.10,所以使用akka.stream.scaladsl.Compression不是一个选项。如果我执行以下操作(为了简单起见,将Play内容替换为玩具应用程序; Play中的结果是相同的):
object AkkaTester extends App {
implicit val system = ActorSystem("system")
implicit val materializer = ActorMaterializer()
val filename = "/tmp/helloworld.txt.gz"
val path = Paths.get(filename)
val sink = StreamConverters.asInputStream()
val akkaInput = new GZIPInputStream(FileIO.fromPath(path).runWith(sink))
var akkaByte = akkaInput.read()
while (akkaByte != -1) print(akkaByte)
akkaInput.close()
system.terminate()
}
...然后它会生成以下内容:
Exception in thread "main" java.io.IOException: akka.stream.impl.io.InputStreamAdapter.read() returned value out of range -1..255: -117
at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:272)
at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:259)
at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:164)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
我是akka流的新手,所以我不确定这是不是一个错误(java docs for InputStream.read()明确说明它应该返回0..255范围内的值,所以它感觉就像一个bug)或者只是我以某种方式误用了akka流。 FWIW,如果我们使用直接的FileInputStream代替akka流,那么在负值上加256会给我们带来的价值。
更新 绝对是一个错误 - 相关代码中的read()方法返回一个原始的有符号字节,这意味着它将在-128到127的范围内,而不是所需的0到255.我已经filed an issue了它