44 votes

Scala : InputStream to Array[Byte]

Avec Scala, quelle est la meilleure façon de lire d'un InputStream vers un tableau d'octets ?

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

 Source.fromInputStream(is).toArray()

48voto

Eastsun Points 9053

Que diriez-vous:

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

Mettre à jour: Use LazyList instead of Stream (depuis la version 2.13.x obsolète)

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

46voto

Andriy Plokhotnyuk Points 3309

Je viens de supprimer le goulot d'étranglement dans 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)

Ou en pur 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
}

N'oubliez pas de fermer un flux d'entrée ouvert dans tous les cas :

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

20voto

Kevin Wright Points 31665

Dans la même veine que la réponse d'Eastsun... J'ai commencé par un commentaire, mais ça a fini par devenir un peu trop long !

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

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

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

14voto

extempore Points 8016
import scala.tools.nsc.io.Streamable
Streamable.bytes(is)

Ne vous souvenez pas à quel point c'est récent : probablement mesuré en jours. Pour revenir à 2.8, c'est plus comme

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

11voto

Wilfred Springer Points 5430

Avec Scala IO , cela devrait fonctionner :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X