Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 314

/ вопрос решён /

Доброго времени суток, уважаемые эксперты! Я, чтобы узнать размер скачиваемого файла использую вот эту функцию.

Вот так она у меня используется :

label1.Caption:=GetUrlSize(HTTP_QUERY_CONTENT_LENGTH, edit1.text);

При этом эта функция очень мендленно работает. Пожалуйста посоветуйте что-нибудь для ускорения или может есть другой, более лучший вариант! Заранее Спасибо!

Приложение:
  1. function GetUrlSize(dwInfoLevel: DWORD; FileURL: string):string;
  2. var
  3. hSession, hFile: hInternet;
  4. dwBuffer: Pointer;
  5. dwBufferLen, dwIndex: DWORD;
  6. begin
  7. Result := '';
  8. hSession := InternetOpen('STEROID Download',
  9. INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  10. if Assigned(hSession) then begin
  11. hFile := InternetOpenURL(hSession, PChar(FileURL), nil, 0,
  12. INTERNET_FLAG_RELOAD, 0);
  13. dwIndex := 0;
  14. dwBufferLen := 20;
  15. if HttpQueryInfo(hFile, dwInfoLevel, @dwBuffer, dwBufferLen, dwIndex)
  16. then Result := PChar(@dwBuffer);
  17. if Assigned(hFile) then InternetCloseHandle(hFile);
  18. InternetCloseHandle(hsession);
  19. end;
  20. end;


eclipse Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: 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().

Приложение:
  1. procedure TImageDownloader.Execute;
  2. var
  3. Buffer: array of Char;
  4. Success: Boolean;
  5. Readed, ReadedTotal: Cardinal;
  6. begin
  7.  
  8. DoOnStatus(False);
  9. FhFile:= InternetOpenUrl(FhInet,
  10. PChar(FURL),
  11. nil,
  12. 0,
  13. INTERNET_FLAG_NO_COOKIES or INTERNET_FLAG_NO_CACHE_WRITE,
  14. 0);
  15.  
  16.  
  17.  
  18. if FhFile = nil
  19. then begin
  20. FErrorCode:= deInternetProblem;
  21. Exit;
  22. end;
  23.  
  24. if (not InternetQueryDataAvailable(FhFile, FFileSize, 0, 0)) or (FFileSize = 0)
  25. then begin
  26. FErrorCode:= deFileNotFound;
  27. Exit;
  28. end;
  29.  
  30. SetLength(Buffer, FBufferSize);
  31.  
  32.  
  33. DoOnStatus(False);
  34.  
  35. ReadedTotal:= 0;
  36. FTimer.Enabled:= True;
  37.  
  38. repeat
  39. Success:= InternetReadFile(FhFile, @Buffer[0], Length(Buffer), Readed);
  40. if Success
  41. then FStream.Write(Buffer[0], Readed);
  42.  
  43. Inc(ReadedTotal, Readed);
  44.  
  45. FDeltaSize:= Readed;
  46. FProgress:= Round(100 * ReadedTotal / FFileSize);
  47. if FProgress > 100
  48. then FProgress:= 100;
  49.  
  50. DoOnStatus(False);
  51. //Sleep(200);
  52. until (Readed = 0) or not Success or MainForm.FCancelled;
  53.  
  54. FTimer.Enabled:= False;
  55.  
  56. if not Success
  57. then FErrorCode:= deInternetProblem;
  58. end;


Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 22 октября 2009, 12:03
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 11; последнее сообщение — 22 октября 2009, 14:46; участников в обсуждении: 3.
min@y™

min@y™ (статус: Доктор наук), 22 октября 2009, 12:44 [#1]:

Цитата:


Оценка за ответ: 5


А где камменты? Помогло или нет?

Цитата:


Хорошо! Ну допустим как организовать закачку файла?


Могу дать исходники готовой проги, там закачка. Без Indy (только WinInet.pas).
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 22 октября 2009, 12:49 [#2]:

Организовать закачку? почитайте мои статьи, на этом же сайте. А конкретно Скачиваем файлы из интернета и Введение в Synapse
Галочка "подтверждения прочтения" - вселенское зло.
eclipse

eclipse (статус: Посетитель), 22 октября 2009, 13:15 [#3]:

не не надо на wininet. он скосяками пашет.
min@y™

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

eclipse (статус: Посетитель), 22 октября 2009, 14:01 [#6]:

Полностью согласен с Вадимом. Ну вот например можно подключить другую dll , не wininet.dll. А в вашей статье про скачку через HTTP не всё работает! так как надо (или я чё не так сделал). В общем ещё паралельный вопрос почему при скачивании обрывается загрузка? а когда продолжаешь загрузку(если удалил файл) файл выползает видимо из кэша уже с таким же размером , который был до этого загружен?(у меня в проге реализована докачка)
Вадим К

Вадим К (статус: Академик), 22 октября 2009, 14:12 [#7]:

Если что то не так работает - так и пишите, угадать я не могу. что конкретно у Вас не заработало.
Почему обрывается закачка? мало чего - может подключение к интернету оборвалось или сервер с той стороны решил так.
wininet.dll может брать с кеша. Но как оно там внутри реализовано - я не знаю, исходников нет.
Галочка "подтверждения прочтения" - вселенское зло.
eclipse

eclipse (статус: Посетитель), 22 октября 2009, 14:23 [#8]:

Блин! Достал Wininet! Вроде всё качает, разобрался! Но при скачивании форма виснет на какое-то время, потом опять действует(можно мышкой н.р. передвинуть), и снова подвисает, как будто рывками идёт. Пожскажите что за ерунда, как избавиться от этих "глюков".
Вадим К

Вадим К (статус: Академик), 22 октября 2009, 14:25 [#9]:

использовать тред. То есть закачка должна идти в отдельном треде. В приведённых статьях есть пример.
Галочка "подтверждения прочтения" - вселенское зло.
eclipse

eclipse (статус: Посетитель), 22 октября 2009, 14:33 [#10]:

Можете пример показать?
Вадим К

Вадим К (статус: Академик), 22 октября 2009, 14:46 [#11]:

ещё раз пишу посмотрите мое сообщение за 11:49 - там есть две ссылки. в первой, в которой рассматриваются инди, как раз с тредом и сделано. А под WinInet, если надо, переделывайте сами. Я WinInet лично не пользуюсь и не буду для этого устанавливать себе винду... (да, у меня дома сейчас нет винды:) )
Галочка "подтверждения прочтения" - вселенское зло.

31 января 2011, 19:36: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:34
Выполнено за 0.03 сек.