Scala:输入流到数组[字节]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4905393/
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
Scala: InputStream to Array[Byte]
提问by rahul
With Scala, what is the best way to read from an InputStream to a bytearray?
使用 Scala,从 InputStream 读取到 bytearray 的最佳方法是什么?
I can see that you can convert an InputStream to char array
我可以看到您可以将 InputStream 转换为 char 数组
Source.fromInputStream(is).toArray()
回答by Eastsun
How about:
怎么样:
Stream.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray
Update:
Use LazyList instead of Stream(since 2.13.x deprecated)
更新:(
Use LazyList instead of Stream自 2.13.x 已弃用)
LazyList.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray
回答by Andriy Plokhotnyuk
Just removed bottleneck in our server code by replacing
刚刚通过替换消除了我们服务器代码中的瓶颈
Stream.continually(request.getInputStream.read()).takeWhile(_ != -1).map(_.toByte).toArray
with
和
org.apache.commons.io.IOUtils.toByteArray(request.getInputStream)
Or in pure Scala:
或者在纯 Scala 中:
def bytes(in: InputStream, initSize: Int = 8192): Array[Byte] = {
var buf = new Array[Byte](initSize)
val step = initSize
var pos, n = 0
while ({
if (pos + step > buf.length) buf = util.Arrays.copyOf(buf, buf.length << 1)
n = in.read(buf, pos, step)
n != -1
}) pos += n
if (pos != buf.length) buf = util.Arrays.copyOf(buf, pos)
buf
}
Do not forget to close an opened input stream in any case:
在任何情况下都不要忘记关闭打开的输入流:
val in = request.getInputStream
try bytes(in) finally in.close()
回答by Kevin Wright
In a similar vein to Eastsun's answer... I started this as a comment, but it ended up getting just a bit to long!
与 Eastsun 的回答类似......我开始是作为评论的,但它最终变得有点长!
I'd caution against using Stream, if holding a reference to the head element then streams can easily consume a lot of memory.
我警告不要使用Stream,如果持有对 head 元素的引用,那么流很容易消耗大量内存。
Given that you're only going to read in the file once, then Iteratoris a much better choice:
鉴于您只会读取文件一次,那么这Iterator是一个更好的选择:
def inputStreamToByteArray(is: InputStream): Array[Byte] =
Iterator continually is.read takeWhile (-1 !=) map (_.toByte) toArray
回答by psp
import scala.tools.nsc.io.Streamable
Streamable.bytes(is)
Don't remember how recent that is: probably measured in days. Going back to 2.8, it's more like
不记得那是多久了:可能以天为单位。回到2.8,更像是
new Streamable.Bytes { def inputStream() = is } toByteArray
回答by Wilfred Springer
回答by pathikrit
With better-files, you can simply do is.bytes
使用Better-files,你可以简单地做is.bytes
回答by TimT
Source.fromInputStream(is).map(_.toByte).toArray
Source.fromInputStream(is).map(_.toByte).toArray
回答by Andrey Onistchuk
How about buffered version of solution based on streams plus ByteArraOutputStream to minimize boilerplate around final array growing?
基于流和 ByteArraOutputStream 的缓冲版本解决方案如何最大限度地减少最终数组增长的样板文件?
val EOF: Int = -1
def readBytes(is: InputStream, bufferSize: Int): Array[Byte] = {
val buf = Array.ofDim[Byte](bufferSize)
val out = new ByteArrayOutputStream(bufferSize)
Stream.continually(is.read(buf)) takeWhile { _ != EOF } foreach { n =>
out.write(buf, 0, n)
}
out.toByteArray
}
回答by Chris Martin
Here's an approach using scalaz-stream:
这是使用 scalaz-stream 的一种方法:
import scalaz.concurrent.Task
import scalaz.stream._
import scodec.bits.ByteVector
def allBytesR(is: InputStream): Process[Task, ByteVector] =
io.chunkR(is).evalMap(_(4096)).reduce(_ ++ _).lastOr(ByteVector.empty)
回答by Jitendra Nandre
We can do it using google API ByteStreams
我们可以使用谷歌 API ByteStreams
import com.google.common.io.ByteStreams
pass the stream to ByteStreams.toByteArray method for conversion
将流传递给 ByteStreams.toByteArray 方法进行转换
ByteStreams.toByteArray(stream)

