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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:47:22  来源:igfitidea点击:

Scala: InputStream to Array[Byte]

scalabytearrayinputstream

提问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

With Scala IO, this should work:

使用Scala IO,这应该有效:

def inputStreamToByteArray(is: InputStream): Array[Byte] = 
   Resource.fromInputStream(in).byteArray

回答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)