views:

108

answers:

4

I found the following example to download web page(string) asynchounously:

let getImage (imageUrl:string) =
    async {
        try 
            let req = WebRequest.Create(imageUrl) :?> HttpWebRequest
            req.UserAgent <- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
            req.Method <- "GET";
            req.AllowAutoRedirect <- true;
            req.MaximumAutomaticRedirections <- 4;
            let! response1 = req.AsyncGetResponse()
            let response = response1 :?> HttpWebResponse
            use stream = response.GetResponseStream()
            use streamreader = new System.IO.StreamReader(stream)
            return! streamreader.AsyncReadToEnd() // .ReadToEnd()
        with
            _ -> return "" // if there's any exception, just return an empty string

    }

It returns a string. However, I need to download an online image(an array of bytes) asynchournously.

Anyone could give me some hint?

A: 

Use http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx

Then you just GetResponseStream and read the bytes.

Lloyd
+2  A: 

You can read the bytes directly from the stream. StreamReader works on strings. It actually inherits TextReader. Alternativly look at using a BinaryReader which works on bytes.

(Since you tagged it as C# I'll write my code sample in C#.)

Stream s = response.GetResponseStream()
MemoryStream memStream = new MemoryStream();
int bytesRead;
byte[] buffer = new byte[0x1000];
for (bytesRead = s.Read(buffer, 0, buffer.Length); bytesRead > 0; bytesRead = s.Read(buffer, 0, buffer.Length))
{
    memStream.Write(buffer, 0, bytesRead);
}
s.Close();
return memStream.ToArray();
Mikael Svenson
A: 

You can convert stream to array of bytes like this (C#)

byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream(stream))
{
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        ms.Write(buffer, 0, read);
    }

    var bytes = ms.ToArray();
}
Sergej Andrejev
+1  A: 

Maybe you can use my answer to another question (here). It asks the google chart API for an image (an URL) and converts the bytes to a Bitmap.

The relevant code:

async {
    let req = HttpWebRequest.Create(..URI HERE..)
    let! response = req.AsyncGetResponse()
    return new Bitmap(response.GetResponseStream())
} |> Async.RunSynchronously
cfern