web-dev-qa-db-fra.com

Scala: InputStream to Array [Octet]

Avec Scala, quel est le meilleur moyen de lire un InputStream en un bytearray?

Je peux voir que vous pouvez convertir un InputStream en tableau de caractères

Source.fromInputStream(is).toArray()
36
rahul

Que diriez-vous:

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

Nous venons de supprimer le goulot d’étranglement de notre code serveur en remplaçant

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

avec

org.Apache.commons.io.IOUtils.toByteArray(request.getInputStream)
37
Andriy Plokhotnyuk

Dans la même veine que la réponse d'Eastsun ... j'ai commencé par un commentaire, mais cela a été un peu long!

Je vous déconseille d'utiliser Stream, si le fait de garder une référence à l'élément head puis les flux peuvent facilement consommer beaucoup de mémoire.

Étant donné que vous n'allez lire qu'une seule fois dans le fichier, alors Iterator est un bien meilleur choix:

def inputStreamToByteArray(is: InputStream): Array[Byte] =
  Iterator continually is.read takeWhile (-1 !=) map (_.toByte) toArray
18
Kevin Wright
import scala.tools.nsc.io.Streamable
Streamable.bytes(is)

Je ne me souviens pas à quel point c'est récent: probablement mesuré en jours. En revenant à 2.8, ça ressemble plus à

new Streamable.Bytes { def inputStream() = is } toByteArray
12
psp

Avec Scala IO , cela devrait fonctionner:

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

Avec better-files , vous pouvez simplement faire is.bytes

4
pathikrit

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

3
TimT

Que diriez-vous de la version tamponnée de la solution basée sur les flux plus ByteArraOutputStream afin de minimiser l’impact autour de la croissance de la matrice finale?

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
}
1
Andrey Onistchuk

Voici une approche utilisant 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)
1
Chris Martin

Une alternative basée sur Scala 2.13's new Seq::unfold :

Seq.unfold(())(_ => Some(is.read.toByte, ()).filter(_._1 != -1)).toArray

et sa variante utilisant le filtrage par motif:

Seq.unfold(())(_ => is.read.toByte match { case -1 => None case b => Some(b, ()) }).toArray
0
Xavier Guihot
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
}
0
Y.H Wong