2009-07-26 13 views
5

Korzystam z następującego kodu, aby pobrać plik wmv za pośrednictwem WebResponse. Używam wątku do wywoływania tej funkcji:Jak używać WebResponse do pobrania pliku .wmv

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(); 
} 

Plik wydaje się być w porządku, ale program Windows Media Viewer nie może poprawnie otworzyć pliku. Jakiś głupi błąd dotyczący braku możliwości obsługi typu pliku.

Co niewiarygodnie łatwo mi brakuje?

+0

Czy zweryfikowałeś, że Windows Media Viewer otwiera plik normalnie poza aplikacją? – thedz

+0

Tak. Powinienem to wyjaśnić. – KevDog

Odpowiedz

5

Wystarczy pobrać jako plik binarny zamiast tekstowy. Oto metoda, która powinna załatwić sprawę.

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(); 
} 
4

Nie rozumiem, dlaczego wypełnienie MemoryStream m jeden bajt na raz, ale wtedy pisanie SR do pliku. W tym momencie uważam, że sr jest pusty, a MemoryStream m nigdy nie jest używany.

Poniżej znajduje się napisany przeze mnie kod do wykonania podobnego zadania. Dostaje WebResponse w porcjach po 32K i zrzuca ją bezpośrednio do pliku.

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. 
} 
+0

Tak, kod ciągle się zmieniał i próbowałem wielu rzeczy. Powinienem był zrobić lepszą robotę sprzątania go przed wysłaniem. Mój błąd. – KevDog

2

Używasz StreamReader i StreamWriter przenieść strumień, ale te zajęcia są do obsługi tekstu. Twój plik jest binarny i istnieje duże prawdopodobieństwo, że sekwencje CR, LF i CR LF zostaną przepełnione podczas przesyłania danych. Jak traktowane są postacie NUL, nie mam pojęcia.

Powiązane problemy