WebClient.OpenRead скачать данные в блоках - PullRequest
0 голосов
/ 15 сентября 2011

Я пытаюсь загрузить данные с помощью объекта 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 () не работает, даже если я указал чтение только столько, сколько переменная fivePercent.Похоже, что он читает весь поток с первой попытки.

Как мне сделать так, чтобы он правильно читал куски?

Спасибо,

Андрей

Ответы [ 3 ]

3 голосов
/ 28 февраля 2012

У вас есть точка с запятой в конце строки с вашим циклом while. Я был очень смущен тем, почему принятый ответ был правильным, пока я не заметил это.

1 голос
/ 15 сентября 2011
do
{
    count = str.Read(fivePercentBuffer, 0, fivePercent);
    fs.Write(fivePercentBuffer, 0, count);
} while (count > 0);
1 голос
/ 15 сентября 2011

Если вам не нужен точный размер блока в 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);
}
...