Цитата:
Сообщение от 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
..., если подправишь сами компоненты, то можно и без промежуточного буфера обойтись.
|
по-моему овчинка выделки не стоит, что мне даст - "без промежуточного буфера обойтись", полагаю некоторую экономию памяти. Стоит ли оно ("подправишь сами компоненты") того.