facebookscaladatabinder

How can I fetch a binary data stream via scala?


I want to download an image for a given url in a scala program. I am trying to do something like the following but all the dispatcher examples I can find talk about text, not data streams. Can anyone point me to examples of downloading binary from a url using dispatch? If I try an use img directly the compiler barfs about Future.

The task I am trying to carry out is retrieving the facebook profile image.

  def copyUrl( uri : String ) : Array[Byte] = {
    val svc = url(uri)
    val img = Http(svc OK as.Bytes)
    for ( i <- img )  {
      println(i)
    }
    // something here but no idea
    img.map(_.toArray)
  }

I get the following compiler error

ProfileImage.scala:31: type mismatch;
[error]  found   : scala.concurrent.Future[Array[Byte]]
[error]  required: Array[Byte]
[error]           img.map(_.toArray)
[error]                  ^
[error] one error found

I have also tried

  def copyUrl( uri : String ) : Array[Byte] = {
    result = scala.io.Source.fromURL(uri).map(_.toByte).toArray
  }

which results in

Exception being returned to browser when processing /oauth/welcome java.nio.charset.MalformedInputException: Input length = 1

Solution

  • Dispatch is returning a Future for the Array[Byte] to you, so you need to apply the Future in order to get the Array[Byte]. Try changing the following line:

    val img = Http(svc OK as.Bytes)()
    

    Notice that I added a () to the end of that line. This will apply the Future, blocking and waiting for the result. Blocking is not ideal, and the dispach Future also supports async callbacks, but this works for the purpose of your example to show what was missing.