Программирование >>  Формирование пользовательского контейнера 

1 ... 65 66 67 [ 68 ] 69 70 71 ... 156


Он препятствует кэшированию файла, зафужаемого из Интернета. Любую дополнительную информацию, свойственную приложению, можно передать в парамефе extra. Поскольку в зафузчике в ней нет необходимости, значение параметра равно нулю. Функция возвращает дескриптор открытого URL-pecypca или null в случае ошибки.

Каждый ответ сервера передается с заголовком. Один из его компонентов содержит версию протокола HTTP. Поскольку зафузчик файла из Интернета требует, чтобы сервер поддерживал протокол HTTP версии 1.1 или более поздние, перед зафузкой файла необходима проверка версии протокола. Она выполняется с помощью вызова функции httpverOKO, как показано далее.

Подтверждает, что поддерживается протокол НТТР/1.1 или более высокие его версии, if(!httpverOK(hlurl))

throw DLExc( HTTP/1.1 not supported. );

Предположим, что версия протокола приемлема, тогда на следующем этапе определяется объем зафужаемого контента с помощью вызова функции HttpQuerylnf о (), приведенного далее.

Получает длину контента, len = sizeof contentlen; if(!HttpQuerylnfо(hlurl,

HTTP QUERY CONTENfT LENGTH

HTTP QUERY FLAG NUMBER,

&contentlen, &len, NULL)) throw DLExc( File or content length not found. );

После возврата функции HttpQueryinfo() длина контента (в байтах) хранится в переменной contentlen. Она автоматически учитывает интервал, заданный в заголовке Range. Следовательно, если файл зафужается целиком, фебуемый интервал данных равен 0- (он соответствует целому файлу) и длина контента равна длине файла. Когда возобновляется прерванная ранее зафузка, величина интервала будет определять начальную точку где-то внутри файла и длина контента будет равна числу оставшихся байтов. Функция HttpQueryinfoo получает информацию из заголовка. Далее приведен ее прототип.

BOOL HttpQuerylnfО (HINTERNET hlurl, DWORD what, LPVOID buf, LPDWORD huflen. LPDWORD index);

Дескриптор запроса, в данном случае возвращенный функции internetopenuri (), передается в параметре hiuri. Именованная константа-



задающая характер получаемой информации, указывается в параметре what. Лия зафузчика требуются две константы. Первая

yTTP QUERY CONTENfT LENGTH

задает запрос длины контента (в данном случае файла), и вторая

HTTP QUERY FLAG NUMBER

хребует, чтобы эта величина была представлена как целое значение. Указатель на буфер, получающий информацию, передается в параметре buf, а указатель на целое, определяющее длину буфера, содержится в параметре buflen. В параметре index можно задать индекс заголовка, но зафузчик не использует этот параметр, поэтому в нем содержится значение null. Функция возвращает true, если она может получить необходимую информацию. Если длина контента недоступна, функция HttpQueryinfoO возвращает false.

Допустим, что длина контента доступна, если длина имеющегося на диске файла меньще ее и длина контента не равна нулю, файл (или его оставшаяся часть) зафужается из Интернета с помощью приведенных далее строк кода. Если существующий файл (при условии, что он есть) не завершен, завершает его загрузку, if (filelen != contentlen && contentlen) do {

Читает буфер of info.

if (! IntemetReadFile (hlurl, &buf,

BUF SIZE, &numrcved)) throw DLExc( Error occurred during download. );

Записьюает буфер на диск.

fout.write( (const char *) buf, numrcved);

if (Ifout.goodO)

thrqw DLExc( Error writing file. );

total += numrcved; обновляет накапливаемьлй итог

Вызьюает функцию update, если она задана. if(update && numrcved > 0)

update(contentlen+filelen, total+filelen);

} while(numrcved > 0); else

if (update)

update(filelen, filelen);



В загрузчике для чтения файла применяется функция IntemetReadFile о

из библиотеки WinlNet, из буфера. В каждом проходе цикла вызывается функция, на которую ссылается переменная update, если ее значение не null. Как уже объяснялось ранее, функция, на которую указывает update, применяется для формирования отчета о состоянии процесса загрузки файла.

Функция IntemetReadFile () очень полезна, так как позволяет вам читать файл из Интернета почти так же, как вы считываете файл с диска. Далее приведен ее прототип.

BOOL IntemetReadFile (HINTERNET hlurl, LPVOID buf, DWORD nuinbytes. LPDWORD numrcvd) ;

Дескриптор файла передается в параметре hiuri. В зафузчике это дескриптор, возвращенный функцией mtemetoperuri {). Указатель на буфер, который будет получать данные, содержится в параметре buf, а количество считываемых байтов - в параметре numbytes. Это число не должно превышать размер buf. Количество действительно считанных байтов возвращается в переменной, на которую указывает парамеф numrcvd. Значение этой переменной станет равно нулю, когда не останется байтов для считывания В случае успешного завершения функция возврашает true, в противном случае - false.

Завершается функция downloadO следующими строками.

} catch(DLExc) fout.close();

IntemetCloseHandle (hlurl) ; IntemetCloseHandle(hlnet) ;

throw; повторно генерирует исключение для использования вызьшаюшей программой (caller)

fout.close();

IntemetCloseHandle (hlurl) ; IntemetCloseHandle (hInet) ; return true;

В случае удачного завершения функция download о закрывает файл и интернет-дескрипторы и возвращает true. Если возникает ошибка, дескрипторы также закрываются, и затем повторно генерируется исключение, что позволяет в пользовательском коде предусмофеть реакцию на ошибку.



1 ... 65 66 67 [ 68 ] 69 70 71 ... 156

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика