我正在尝试使用Webclient对象在块5%的每个下载数据。原因是我需要报告每个下载块的进度。
下面是我写的代码来完成这个任务: 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()也不起作用。看起来它在第一次尝试中读取了整个流。
我怎样才能使它正确地读取块?
谢谢,
安德烈
在while循环的行尾有一个分号。我很困惑为什么被接受的答案是正确的,直到我注意到
do
{
count = str.Read(fivePercentBuffer, 0, fivePercent);
fs.Write(fivePercentBuffer, 0, count);
} while (count > 0);
如果你不需要精确的5%块大小,你可能想看看异步下载方法,如DownloadDataAsync或OpenReadAsync。
它们在每次下载新数据和进度变化时触发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);
}