|
Вопрос # 3 314/ вопрос решён / |
|
Доброго времени суток, уважаемые эксперты! Я, чтобы узнать размер скачиваемого файла использую вот эту функцию.
Вот так она у меня используется :
label1.Caption:=GetUrlSize(HTTP_QUERY_CONTENT_LENGTH, edit1.text);
При этом эта функция очень мендленно работает. Пожалуйста посоветуйте что-нибудь для ускорения или может есть другой, более лучший вариант! Заранее Спасибо!
Приложение: Переключить в обычный режим- function GetUrlSize(dwInfoLevel: DWORD; FileURL: string):string;
- var
- hSession, hFile: hInternet;
- dwBuffer: Pointer;
- dwBufferLen, dwIndex: DWORD;
- begin
- Result := '';
- hSession := InternetOpen('STEROID Download',
- INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
- if Assigned(hSession) then begin
- hFile := InternetOpenURL(hSession, PChar(FileURL), nil, 0,
- INTERNET_FLAG_RELOAD, 0);
- dwIndex := 0;
- dwBufferLen := 20;
- if HttpQueryInfo(hFile, dwInfoLevel, @dwBuffer, dwBufferLen, dwIndex)
- then Result := PChar(@dwBuffer);
- if Assigned(hFile) then InternetCloseHandle(hFile);
- InternetCloseHandle(hsession);
- end;
- end;
 |
Вопрос задал: eclipse (статус: Посетитель)
Вопрос отправлен: 22 октября 2009, 11:45
Состояние вопроса: решён, ответов: 2.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, eclipse!
Знаю досточно простой и рабочий метод - используя Indy. В любом случае (если даже будете использовать другие методы) для запроса размера файла без собственно скачивания файла надо сделать так называемый HEAD запрос.
С Indy это делается просто
IdHTTP1.Head(url );
и теперь будет доступен размер
IdHTTP1.Response.ContentLength
и последнее изменение
IdHTTP1.Response.LastModified
Но следует помнить, что в некоторых случаях сервера не возвращают размер. Это абсолютно нормально.
для нагрузки почитайте ещё это http://parsing-and-i.blogspot.com/2009/04/http-protocol-http-requests.html
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 22 октября 2009, 11:58
Оценка за ответ: 5
Комментарий к оценке: Хорошо! Ну допустим как организовать закачку файла?
|
Ответ #2. Отвечает эксперт: min@y™
Я для этих целей юзаю функцию InternetQueryDataAvailable().
Приложение: Переключить в обычный режим- procedure TImageDownloader.Execute;
- var
- Buffer: array of Char;
- Success: Boolean;
- Readed, ReadedTotal: Cardinal;
- begin
-
- DoOnStatus(False);
- FhFile:= InternetOpenUrl(FhInet,
- PChar(FURL),
- nil,
- 0,
- INTERNET_FLAG_NO_COOKIES or INTERNET_FLAG_NO_CACHE_WRITE,
- 0);
-
-
-
- if FhFile = nil
- then begin
- FErrorCode:= deInternetProblem;
- Exit;
- end;
-
- if (not InternetQueryDataAvailable(FhFile, FFileSize, 0, 0)) or (FFileSize = 0)
- then begin
- FErrorCode:= deFileNotFound;
- Exit;
- end;
-
- SetLength(Buffer, FBufferSize);
-
-
- DoOnStatus(False);
-
- ReadedTotal:= 0;
- FTimer.Enabled:= True;
-
- repeat
- Success:= InternetReadFile(FhFile, @Buffer[0], Length(Buffer), Readed);
- if Success
- then FStream.Write(Buffer[0], Readed);
-
- Inc(ReadedTotal, Readed);
-
- FDeltaSize:= Readed;
- FProgress:= Round(100 * ReadedTotal / FFileSize);
- if FProgress > 100
- then FProgress:= 100;
-
- DoOnStatus(False);
- //Sleep(200);
- until (Readed = 0) or not Success or MainForm.FCancelled;
-
- FTimer.Enabled:= False;
-
- if not Success
- then FErrorCode:= deInternetProblem;
- end;
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 22 октября 2009, 12:03
Оценка за ответ: 5
|
Мини-форум вопроса
Всего сообщений: 11; последнее сообщение — 22 октября 2009, 14:46; участников в обсуждении: 3.
|
min@y™ (статус: Доктор наук), 22 октября 2009, 12:44 [#1]:
Цитата:
Оценка за ответ: 5
А где камменты? Помогло или нет?
Цитата:
Хорошо! Ну допустим как организовать закачку файла?
Могу дать исходники готовой проги, там закачка. Без Indy (только WinInet.pas).
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
eclipse (статус: Посетитель), 22 октября 2009, 13:15 [#3]:
не не надо на wininet. он скосяками пашет.
|
|
min@y™ (статус: Доктор наук), 22 октября 2009, 13:26 [#4]:
Цитата (eclipse):
не не надо на wininet. он скосяками пашет.
Откуда такая информация? Прочитал на заборе?
А по-другому не получится. Все проги юзают библиотеку c:\WINDOWS\system32\wininet.dll для работы в инете, а модуль WinInet.pas - это интерфейсный модуль для этой библиотеки. Ты в его исходник глянь, там описаны экспортированные из dll функции, типа этой:
function InternetConnect; external winetdll name 'InternetConnectA';
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Вадим К (статус: Академик), 22 октября 2009, 13:51 [#5]:
Цитата (undefined):
Все проги юзают библиотеку c:\WINDOWS\system32\wininet.dll для работы в инете
Очень спорное утверждение. Вот у меня есть приложение, которое "работает в инете" (сама фраза абсурдна, но... это цитата). и нет там wininet.dll. Что я делаю не правильно ?
На самом деле надо только WinSock или другая реализация сокетов (беркли например).
Галочка "подтверждения прочтения" - вселенское зло.
|
|
eclipse (статус: Посетитель), 22 октября 2009, 14:01 [#6]:
Полностью согласен с Вадимом. Ну вот например можно подключить другую dll , не wininet.dll. А в вашей статье про скачку через HTTP не всё работает! так как надо (или я чё не так сделал). В общем ещё паралельный вопрос почему при скачивании обрывается загрузка? а когда продолжаешь загрузку(если удалил файл) файл выползает видимо из кэша уже с таким же размером , который был до этого загружен?(у меня в проге реализована докачка)
|
|
Вадим К (статус: Академик), 22 октября 2009, 14:12 [#7]:
Если что то не так работает - так и пишите, угадать я не могу. что конкретно у Вас не заработало.
Почему обрывается закачка? мало чего - может подключение к интернету оборвалось или сервер с той стороны решил так.
wininet.dll может брать с кеша. Но как оно там внутри реализовано - я не знаю, исходников нет.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
eclipse (статус: Посетитель), 22 октября 2009, 14:23 [#8]:
Блин! Достал Wininet! Вроде всё качает, разобрался! Но при скачивании форма виснет на какое-то время, потом опять действует(можно мышкой н.р. передвинуть), и снова подвисает, как будто рывками идёт. Пожскажите что за ерунда, как избавиться от этих "глюков".
|
|
Вадим К (статус: Академик), 22 октября 2009, 14:25 [#9]:
использовать тред. То есть закачка должна идти в отдельном треде. В приведённых статьях есть пример.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
eclipse (статус: Посетитель), 22 октября 2009, 14:33 [#10]:
Можете пример показать?
|
|
Вадим К (статус: Академик), 22 октября 2009, 14:46 [#11]:
ещё раз пишу посмотрите мое сообщение за 11:49 - там есть две ссылки. в первой, в которой рассматриваются инди, как раз с тредом и сделано. А под WinInet, если надо, переделывайте сами. Я WinInet лично не пользуюсь и не буду для этого устанавливать себе винду... (да, у меня дома сейчас нет винды )
Галочка "подтверждения прочтения" - вселенское зло.
|
31 января 2011, 19:36: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|