scala 如何将 Source[ByteString, Any] 转换为 InputStream
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30502844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert Source[ByteString, Any] to InputStream
提问by kostya
akka-http represents a file uploaded using multipart/form-data encoding as Source[ByteString, Any]. I need to unmarshal it using Java library that expects an InputStream.
akka-http 表示使用 multipart/form-data 编码上传的文件为Source[ByteString, Any]. 我需要使用需要InputStream.
How Source[ByteString, Any]can be turned into an InputStream?
怎么Source[ByteString, Any]能变成一个InputStream?
采纳答案by Bennie Krijger
As of version 2.x you achieve this with the following code:
从 2.x 版开始,您可以使用以下代码实现此目的:
import akka.stream.scaladsl.StreamConverters
...
val inputStream: InputStream = entity.dataBytes
.runWith(
StreamConverters.asInputStream(FiniteDuration(3, TimeUnit.SECONDS))
)
请参阅:http: //doc.akka.io/docs/akka-stream-and-http-experimental/2.0.1/scala/migration-guide-1.0-2.x-scala.html
Note: was broken in version 2.0.2 and fixed in 2.4.2
注意:在 2.0.2 版本中被破坏并在 2.4.2 中修复
回答by cmbaxter
You could try using an OutputStreamSinkthat writes to a PipedOutputStreamand feed that into a PipedInputStreamthat your other code uses as its input stream. It's a little rough of an idea but it could work. The code would look like this:
您可以尝试使用OutputStreamSink写入 a 的 aPipedOutputStream并将其提供给PipedInputStream您的其他代码用作其输入流的 a 。这是一个有点粗糙的想法,但它可以工作。代码如下所示:
import akka.util.ByteString
import akka.stream.scaladsl.Source
import java.io.PipedInputStream
import java.io.PipedOutputStream
import akka.stream.io.OutputStreamSink
import java.io.BufferedReader
import java.io.InputStreamReader
import akka.actor.ActorSystem
import akka.stream.ActorFlowMaterializer
object PipedStream extends App{
implicit val system = ActorSystem("flowtest")
implicit val mater = ActorFlowMaterializer()
val lines = for(i <- 1 to 100) yield ByteString(s"This is line $i\n")
val source = Source(lines)
val pipedIn = new PipedInputStream()
val pipedOut = new PipedOutputStream(pipedIn)
val flow = source.to(OutputStreamSink(() => pipedOut))
flow.run()
val reader = new BufferedReader(new InputStreamReader(pipedIn))
var line:String = reader.readLine
while(line != null){
println(s"Reader received line: $line")
line = reader.readLine
}
}
回答by Juan José Vázquez Delgado
You could extract an interator from ByteString and then get the InputStream. Something like this (pseudocode):
您可以从 ByteString 中提取一个 interator,然后获取 InputStream。像这样(伪代码):
source.map { data: ByteString =>
data.iterator.asInputStream
}
Update
更新
A more elaborated sample starting with a Multipart.FormData
从 Multipart.FormData 开始的更详细的示例
def isSourceFromFormData(formData: Multipart.FormData): Source[InputStream, Any] =
formData.parts.map { part =>
part.entity.dataBytes
.map(_.iterator.asInputStream)
}.flatten(FlattenStrategy.concat)

