Scala:输入流到数组[字节]

发布于 2024-10-16 03:28:17 字数 150 浏览 6 评论 0原文

使用 Scala,从 InputStream 读取字节数组的最佳方法是什么?

我可以看到您可以将 InputStream 转换为 char 数组

Source.fromInputStream(is).toArray()

With Scala, what is the best way to read from an InputStream to a bytearray?

I can see that you can convert an InputStream to char array

Source.fromInputStream(is).toArray()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

想念有你 2024-10-23 03:28:17

怎么样:

Stream.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray

更新:使用 LazyList 而不是 Stream (因为 Stream 在 Scala 3 中已弃用)

LazyList.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray

How about:

Stream.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray

Update: use LazyList instead of Stream (since Stream is deprecated in Scala 3)

LazyList.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray
缱倦旧时光 2024-10-23 03:28:17

Or来消除服务器代码中的瓶颈

Stream.continually(request.getInputStream.read()).takeWhile(_ != -1).map(_.toByte).toArray

刚刚通过在纯 Scala 中替换为

org.apache.commons.io.IOUtils.toByteArray(request.getInputStream)

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
}

在任何情况下都不要忘记关闭打开的输入流:

val in = request.getInputStream
try bytes(in) finally in.close()

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:

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()
∞梦里开花 2024-10-23 03:28:17

与 Eastsun 的回答类似……我一开始是作为评论,但最终变得有点长了!

我警告不要使用 Stream,如果持有对 head 元素的引用,那么流很容易消耗大量内存。

鉴于您只会读取文件一次,那么 Iterator 是一个更好的选择:

def inputStreamToByteArray(is: InputStream): Array[Byte] =
  Iterator continually is.read takeWhile (-1 !=) map (_.toByte) toArray

In a similar vein to Eastsun's answer... I started this as a comment, but it ended up getting just a bit to long!

I'd caution against using Stream, if holding a reference to the head element then streams can easily consume a lot of memory.

Given that you're only going to read in the file once, then Iterator is a much better choice:

def inputStreamToByteArray(is: InputStream): Array[Byte] =
  Iterator continually is.read takeWhile (-1 !=) map (_.toByte) toArray
对岸观火 2024-10-23 03:28:17
import scala.tools.nsc.io.Streamable
Streamable.bytes(is)

不记得那是多久以前的事:可能以天为单位。回到2.8,它更像是

new Streamable.Bytes { def inputStream() = is } toByteArray
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

new Streamable.Bytes { def inputStream() = is } toByteArray
吖咩 2024-10-23 03:28:17

使用 Scala IO,这应该可以工作:

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

With Scala IO, this should work:

def inputStreamToByteArray(is: InputStream): Array[Byte] = 
   Resource.fromInputStream(in).byteArray
坚持沉默 2024-10-23 03:28:17

使用 better-files,您可以简单地执行 is.bytes

With better-files, you can simply do is.bytes

抹茶夏天i‖ 2024-10-23 03:28:17

Source.fromInputStream(is).map(_.toByte).toArray

Source.fromInputStream(is).map(_.toByte).toArray

情丝乱 2024-10-23 03:28:17

基于流和 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
}

How about buffered version of solution based on streams plus ByteArraOutputStream to minimize boilerplate around final array growing?

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
}
滥情空心 2024-10-23 03:28:17

这是使用 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)

Here's an approach using 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)
悲念泪 2024-10-23 03:28:17

从 JDK 9 开始:

is.readAllBytes()

Since JDK 9:

is.readAllBytes()
软糯酥胸 2024-10-23 03:28:17

我们可以使用 Google API ByteStreams

com.google.common.io.ByteStreams

将流传递给 ByteStreams.toByteArray 方法进行转换

ByteStreams.toByteArray(stream)

We can do using Google API ByteStreams

com.google.common.io.ByteStreams

pass the stream to ByteStreams.toByteArray method for conversion

ByteStreams.toByteArray(stream)
挽袖吟 2024-10-23 03:28:17
def inputStreamToByteArray(is: InputStream): Array[Byte] = {
    val buf = ListBuffer[Byte]()
    var b = is.read()
    while (b != -1) {
        buf.append(b.byteValue)
        b = is.read()
    }
    buf.toArray
}
def inputStreamToByteArray(is: InputStream): Array[Byte] = {
    val buf = ListBuffer[Byte]()
    var b = is.read()
    while (b != -1) {
        buf.append(b.byteValue)
        b = is.read()
    }
    buf.toArray
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文