views:

521

answers:

3

I'm using the following code to grab a wmv file through a WebResponse. I'm using a thread to call this function:

static void GetPage(object data)
{
    // Cast the object to a ThreadInfo
    ThreadInfo ti = (ThreadInfo)data;

    // Request the URL
    WebResponse wr = WebRequest.Create(ti.url).GetResponse();

    // Display the value for the Content-Length header
    Console.WriteLine(ti.url + ": " + wr.Headers["Content-Length"]);
    string toBeSaved = @"C:\Users\Kevin\Downloads\TempFiles" + wr.ResponseUri.PathAndQuery;        
    StreamWriter streamWriter = new StreamWriter(toBeSaved);

    MemoryStream m = new MemoryStream();
    Stream receiveStream = wr.GetResponseStream();
    using (StreamReader sr = new StreamReader(receiveStream))
    {
        while (sr.Peek() >= 0)
        {
            m.WriteByte((byte)sr.Read());
        }
        streamWriter.Write(sr.ReadToEnd());
        sr.Close();
        wr.Close();
    }

    streamWriter.Flush();
    streamWriter.Close();

    // streamReader.Close();
    // Let the parent thread know the process is done
    ti.are.Set();

    wr.Close();
}

The file seems to download just fine, but Windows Media Viewer cannot open the file properly. Some silly error about not being able to support the file type.

What incredibly easy thing am I missing?

+3  A: 

I do not understand why you are filling MemoryStream m one byte at a time, but then writing the sr to the file. At that point, I believe the sr is empty, and MemoryStream m is never used.

Below is some code I wrote to do a similar task. It gets a WebResponse in 32K chunks at a time, and dumps it directly to a file.

public void GetStream()
{
    // ASSUME: String URL is set to a valid URL.
    // ASSUME: String Storage is set to valid filename.

    Stream response = WebRequest.Create(URL).GetResponse().GetResponseStream();
    using (FileStream fs = File.Create(Storage)) 
    {
        Byte[] buffer = new Byte[32*1024];
        int read = response.Read(buffer,0,buffer.Length);
        while (read > 0)
        {
            fs.Write(buffer,0,read);
            read = response.Read(buffer,0,buffer.Length);
        }
    }
    // NOTE: Various Flush and Close of streams and storage not shown here.
}
abelenky
Yeah, the code kept getting changed and I was trying multiple things. I should have done a better job of cleaning it up before posting. My bad.
KevDog
+2  A: 

You are using a StreamReader and a StreamWriter to transfer your stream, but those classes are for handling text. Your file is binary and chances are that sequences of CR, LF and CR LF may get clobbered when you transfer the data. How NUL characters are handled I have no idea.

Martin Liversage
A: 

You just need to download it as binary instead of text. Here's a method that should do the trick for you.

public void DownloadFile(string url, string toLocalPath)
{
    byte[] result = null;
    byte[] buffer = new byte[4097];

    WebRequest wr = WebRequest.Create(url);

    WebResponse response = wr.GetResponse();
    Stream responseStream = response.GetResponseStream;
    MemoryStream memoryStream = new MemoryStream();

    int count = 0;

    do {
        count = responseStream.Read(buffer, 0, buffer.Length);
        memoryStream.Write(buffer, 0, count);

        if (count == 0) {
            break;
        }
    }
    while (true);

    result = memoryStream.ToArray;

    FileStream fs = new FileStream(toLocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);

    fs.Write(result, 0, result.Length);

    fs.Close();
    memoryStream.Close();
    responseStream.Close();
}
routeNpingme