Ну вот наконец-то я созрел для написании статьи, где я хочу рассказать о том, как можно скачать файл из Интернет без зависания формы, то есть с использованием потоков. Сказать честно, сам в потоках давно разбираюсь так до конца и не разобрался, но маленькую программку по закачке файлов я смог всетаки, наконец-то, написать. Конечно было бы хорошо рассказать немного о потоках Вам, но я в них не силен еще сам, то там что-то прочитал, то там, то там и немного сворганил. Вы наверное замечали, что при скачивании файла из Интернет форма на время этой скачки просто-напросто зависает, что не очень удобно и пользователю ничего нельзя сделать в это время. Если в Indy есть такой замечательный компонент как TidAntiFreeze, то в wininet его совсем нету. Да и то, если у Вас на форме находится TidAntiFreeze, то все равно форма ваша, где происходит скачка немного подвисает, а если у Вас нету в этой время подключения к сети Интернет, то это вообще полный «зависон» формы. Так что тут на это дело приходят потоки.

Как скачать файлы из интернет с помощью wininet, я рассказывал в этой статье. Так, что повторяться уже не буду, мы будем использовать тоже самое, только с помощью потоков это все дело организуем. В Delphi есть класс TThread, специально предназначенный для работы с потоками. Его необходимо описать, что я и сделал, и вот что у меня получилось

type
  TMyThread = class(TThread) //Новый класс
  private
    answer: Integer;
  protected
    procedure ShowResult;
    procedure Execute; override;
  end;

Процедура ShowResult - показыват сколько скачало у меня. А процедура Execute - выполняет действия потока. Вот что я написал на процедуру Execute

procedure TMyThread.Execute;
var
  session,url:HInternet;
  appName:WideString;
  BufArr:array[1..1024] of byte;
  BufLen:DWORD;
  F:File;
begin
   answer:=0;
   appName:=ExtractFileName(Application.ExeName);
   session:=InternetOpen(Pchar(appName),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
   url:=InternetOpenUrl(session,PAnsiChar('http://belarusy.by/file/videos/src/58346.flv'),nil,0,0,0);
   AssignFile(F,'C:\1.flv');
   Rewrite(F,1);
   repeat
    InternetReadFile(url,@BufArr,SizeOf(BufArr),BufLen);
    BlockWrite(F,BufArr,BufLen);
    answer:=answer+BufLen;
   until BufLen=0;
   CloseFile(F);
   InternetCloseHandle(session);
   Synchronize(ShowResult);
end;

То есть все, что и писал в предыдущей статье по скачиванию файлов.  Только добавился метод Synchronize(ShowResult), который синхронизирует результат. Далее процедура ShowResult у меня выглядет следующим образом

procedure TMyThread.ShowResult;
begin
 Form1.Edit1.Text := IntToStr(answer);
end;

А вот на событие OnClick Button1 я написал следующий код

procedure TForm1.Button1Click(Sender: TObject);
var
 MyThread:TMyThread;
begin
   MyThread := TMyThread.Create(False);
end;

Мы создаем объект нашего потока, а False означает, что мы начинаем вызывать сразу метод Excecute. В следующей статье я хотел бы рассказать как с помощью потоков, скачать файл используя TIdHTTP.

Автор статьи - Andrey53

Метки: , , ,




К записи “Качаем файл из Интернет с использованием потоков” оставлено комментариев: 3.

  1. Александр:

    интересно про потоки,можно еще что нибудь выложить

  2. Александр:

    где найти инфу по потокам,все делают замечания автору но негде нет инфы ,спецы напишите

  3. Юрий:

    Очень понравилась ваша статья.
    Разбирался правда долго, неделю как начал осваивать Delphi.

    Если вас не затруднит, ответьте на пару вопросов:
    1. url:=InternetOpenUrl(session,PAnsiChar(‘http://belarusy.by/file/videos/src/58346.flv’),nil,0,0,0); у меня ошибка, может PChar вместо PAnsiChar? Так по крайней мере работает.
    2. Если больше 10 клиентов начнут скачивать файл, что произойдет с сервером?
    3. Можно ли потоковую раздачу как то настроить на сервере (php) или это лишнее?
    4. Наверное как то можно и передачу файлов организовать на сервер по аналогии, нету ли примеров?
    5. Можно ли через Delphi создавать папки на сервере (HTTP предпочтительно).

    Еще раз спасибо за статью, она мне очень помогла.

Оставить комментарий

Вы можете использовать следующие теги:

*