问题
I am trying to download data using a Webclient object in chunks of 5% each. The reason is that I need to report progress for each downloaded chunk.
Here is the code I wrote to do this task:
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();
}
The problem - when it gets to str.Read(), it pauses as much as reading the whole stream, and then count is 0. So the while() doesn't work, even if I specified to read only as much as the fivePercent variable. It just looks like it reads the whole stream in the first try.
How can I make it so that it reads chunks properly?
Thanks,
Andrei
回答1:
do
{
count = str.Read(fivePercentBuffer, 0, fivePercent);
fs.Write(fivePercentBuffer, 0, count);
} while (count > 0);
回答2:
You have a semi-colon on the end of the line with your while loop. I was very confused as to why the accepted answer was right, until I noticed that.
回答3:
If you don't need an exact 5% chunk size, you may want to look into the async download methods such as DownloadDataAsync or OpenReadAsync.
They fire the DownloadProgressChanged event each time new data is downloaded and the progress changes, and the event provides the percentage completion in the event args.
Some example code:
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);
}
来源:https://stackoverflow.com/questions/7424117/webclient-openread-download-data-in-chunks