2011-02-05 178 views
31

隨着Scala,從InputStream讀取字節數組的最佳方式是什麼?Scala:輸入流到數組[字節]

我可以看到,你可以轉換一個InputStream到字符數組

Source.fromInputStream(is).toArray() 

回答

37

如何:

Stream.continually(is.read).takeWhile(_ != -1).map(_.toByte).toArray 
0
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

列表[字節]有一個方法「添加」? – Eastsun 2011-02-05 08:06:30

+0

好問題。我只是編輯它使用可變的ListBuffer – 2011-02-05 08:30:31

11
import scala.tools.nsc.io.Streamable 
Streamable.bytes(is) 

不記得怎麼最近是:在天大概測量。讓我們回到2.8,它更像

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

使用scala.tools包中的東西安全嗎?他們甚至是標準庫的一部分嗎? – 2011-02-05 07:20:50

+0

不可以。但是如果你想知道如何寫它,那就是了。 – extempore 2011-02-05 08:14:55

+1

它現在似乎已經轉移到了更標準的`scala.reflect.io`軟件包。 – Thilo 2015-10-07 02:29:50

17

本着同樣的精神,以東日的答案......我一開始這是一個評論,但它最終得到只是有點要多久!

我對使用Stream要小心,如果持有頭元素的引用,那麼流很容易消耗大量內存。

既然你只打算在文件中一次讀,然後Iterator是一個更好的選擇:

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

隨着Scala IO,這應該工作:

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

只是刪除瓶頸在我們的服務器代碼中通過替換

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

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

Source.fromInputStream(是).MAP(_ toByte).toArray

1

這裏有一個方法使用scalaz流:

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)