Показать сообщение отдельно
  #3  
Старый 05.05.2015, 01:36
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
можно создать массив... Каждый поток там проставит флажок, что завершился. А главный поток просто проверяет массивы состояний...
если так
Код:
procedure TForm1.Button1Click(Sender: TObject);
var   i: Byte;         TDLoad;
begin
 .................................
 for i:= 0 to {кол-во частей} do
 begin
  ..................................
  dl:= TDLoad.Create(True); 
  .....................................
 end;
  ...................................
 while {не все потоки поставили флажок (завершились)} do Sleep(1000);
end;
тогда получается - главный поток будет занят до завершения всех потоков, другой вариант - таймер, интервал, скажем секунда. В обоих случаях можно спокойно обойтись без массива, и даже не обязательно знать заранее кол-во потоков (частей файла)
Код:
var
  Form1: TForm1;
  TrCnt: Byte;
  CntLock: TCriticalSection;

implementation
Код:
procedure TForm1.Button1Click(Sender: TObject);
var i: Byte;
    dl: TDLoad;
begin
 .................................
 for i:= 0 to {кол-во частей} do
 begin
  ..................................
  CntLock.Enter; Inc(TrCnt); CntLock.Leave;
 end;
  ...................................
 while TrCnt>0 do Sleep(1000);
end;
ну или через таймер
Код:
procedure TDLoad.Execute;
var h: TIdHTTP;
     Strim: TMemoryStream;
begin
  ............................
  h.Get(URL,Strim); //если все удачно, то в Strim мы имеем кусок нужного файла
  ...............................
 h.Free;
  CntLock.Enter; Dec(TrCnt); CntLock.Leave;
end;
Цитата:
Сообщение от lmikle
2. Т.к. ты знаешь размер файла до начала его скачивания, то сначала создай соотв файл (читай - TFileStream) и ссылку на него передавай каждому потоку вместе с началом и концом. Каждый поток скачает данные во временный буфер (TMemorystream), а потом просто запишет его в нужное место файла.
Код:
type
    TDLoad = class(TThread)
    private
     Strim: TFileStream;
  ..............................
    protected
     procedure Execute; override;
    end;
 
{ TDLoad }
 
procedure TDLoad.Execute;
var h: TIdHTTP;
     Buf: TMemoryStream;
begin
................................
 Buf:= TMemoryStream.Create;
  ............................
 try
  h.Get(URL,Strim); 
 Except
  on E : Exception do ShowMessage('Нету'+#13#10+IntToStr(h.ResponseCode)); 
 end;
 h.Free;
 CntLock.Enter;
 Strim.Position:=S; //не уверен
 Strim.CopyFrom(Buf,Buf.Size); //не уверен
 CntLock.Leave;
 Buf.Free;
end;
Код:
procedure TForm1.Button2Click(Sender: TObject);
var i: Byte;
    dl: TDLoad;
    fs: TFileStream;
begin
 fs:= TFileStream.Create('D:\cashe\001.mp4',fmCreate);
 fs.Size:={.Response.ContentLength};
 for i:= 0 to {кол-во частей} do
 begin
  dl:= TDLoad.Create(True);
  dl.S:= //Начало
  dl.E:= //Конец
  dl.Strim:= fs; //здесь не уверен
  dl.Resume;
 end;
end;
только, по-моему тут нет необходимости отлавливать окончания потоков.
Цитата:
Сообщение от lmikle
..., если подправишь сами компоненты, то можно и без промежуточного буфера обойтись.
по-моему овчинка выделки не стоит, что мне даст - "без промежуточного буфера обойтись", полагаю некоторую экономию памяти. Стоит ли оно ("подправишь сами компоненты") того.
Ответить с цитированием