2011-09-14 18 views
0

我正嘗試使用WebClient對象以5%的塊爲單位下載數據。原因是我需要爲每個下載的塊報告進度。WebClient.OpenRead以塊爲單位下載數據

這裏是我寫的做這個任務的代碼:

private void ManageDownloadingByExtractingContentDisposition(WebClient client, Uri uri) 
    { 
     //Initialize the downloading stream 
     Stream str = client.OpenRead(uri.PathAndQuery); 

     WebHeaderCollection whc = client.ResponseHeaders; 
     string contentDisposition = whc["Content-Disposition"]; 
     string contentLength = whc["Content-Length"]; 
     string fileName = contentDisposition.Substring(contentDisposition.IndexOf("=") +1); 

     int totalLength = (Int32.Parse(contentLength)); 
     int fivePercent = ((totalLength)/10)/2; 

     //buffer of 5% of stream 
     byte[] fivePercentBuffer = new byte[fivePercent]; 

     using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) 
     { 
      int count; 
      //read chunks of 5% and write them to file 
      while((count = str.Read(fivePercentBuffer, 0, fivePercent)) > 0); 
      { 
       fs.Write(fivePercentBuffer, 0, count); 
      } 
     } 
     str.Close(); 
    } 

的問題 - 當它到達str.Read(),它會暫停不亞於讀全碼流,然後計數爲0所以while()不起作用,即使我指定只讀取5Percent變量。它看起來像在第一次嘗試中讀取整個流。

我該如何使它正確讀取塊?

感謝,

安德烈

+1

註冊WebClient.DownloadProgressChanged事件,然後調用WebClient.DownloadDataAsync()。您可以更新事件回調中的進度。 – Jon

回答

1
do 
{ 
    count = str.Read(fivePercentBuffer, 0, fivePercent); 
    fs.Write(fivePercentBuffer, 0, count); 
} while (count > 0); 
+0

這個作品,謝謝。不知道它爲什麼會起作用。可能是因爲計數被修改後。 –

1

如果你並不需要一個精確的5%塊大小,你可能要考慮異步下載方法如DownloadDataAsyncOpenReadAsync

每次下載新數據並且進度改變時,它們都會觸發DownloadProgressChanged事件,並且該事件在事件參數中提供完成百分比。

一些示例代碼:

WebClient client = new WebClient(); 
Uri uri = new Uri(address); 

// Specify a progress notification handler. 
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback); 

client.DownloadDataAsync(uri); 

static void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e) 
{ 
    // Displays the operation identifier, and the transfer progress. 
    Console.WriteLine("{0} downloaded {1} of {2} bytes. {3} % complete...", 
     (string)e.UserState, 
     e.BytesReceived, 
     e.TotalBytesToReceive, 
     e.ProgressPercentage); 
} 
+0

感謝您的建議,但應用程序不允許異步下載。我必須找到一種處理同步下載報告進度的方法。 –

+1

你能否澄清你的意思是'應用程序不允許異步下載'?你的應用程序如何防止這一點? –

+0

我的應用程序需要下載多個文件,並且需要一次一個地同步,這只是一個任務請求。最初爲了做到這一點,我使用了同步下載的webclient.DownloadFile(),但我也需要做進度報告,所以我想用webClient.OpenRead()來報告塊。 –

3

你必須與你的while循環行的末尾分號。我很困惑,爲什麼接受的答案是正確的,直到我注意到這一點。