•  

ГлавнаяIndyЧастые вопросы по Indy → Progressbar при закачивании файла на фтп

Создано: 24.05.2014 23:21:57 · Исправлено: 24.05.2014 23:21:57 · Прочтений: 1253

Добрый день, необходима помощь с progressbar при закачивании файла на фтп, а именно необходимо вычеслить размер закачиваемого файла и отобразить сам процесс в progressbar в виде полоски прогресса и отображения в label прогресса общий размер файла\количество закаченный байт.
Вот моя процедура:

procedure tbase.ftp_send(login,pass,host,local_patch,remote_patch,mask:string);
var
ftp_list:tfilelistbox;
ii:integer;
begin
base.FTP.Disconnect;
base.Memo.Lines.Add(------------------------------);
base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Подключаемся к FTP://+login+:[email protected]+host+remote_patch);
ftp_list:=tfilelistbox.Create(base.panel2);
ftp_list.Parent:=base.Panel2;
ftp_list.Mask:=mask;
ftp_list.Directory:=local_patch;
// Хост настройки
base.Ftp.Host:=Host;
base.FTP.Username:=login;
base.FTP.Password:=Pass;
//Коннектимся
if ftp_list.Items.Count>0 then
    try
    base.FTP.Connect;
    base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Успешно подключены);
    if length(remote_patch)>1 then
    base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Изменяем директорию на :+remote_patch);
    base.ftp.ChangeDir(remote_patch);//меняем директорию
    for ii := 0 to ftp_List.items.Count - 1 do
        begin
        ftp_list.ItemIndex:=ii; //листаем файлы в диретории
        base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Загружаем файл на фтп: +ftp_list.FileName);
        if FTP.Size(ExtractFileName(ftp_list.FileName))=-1 then //пытаемся по размеру файла определить есть ли такой файл в удаленной диретории
        base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Такого файла на фтп нет, заливаем) else
        base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Такой файл на фтп есть, перезаписываем);
        // Отправляем файлы
        base.Ftp.Put(ftp_list.FileName,remote_patch+ExtractFileName(ftp_list.FileName),true); // отправляем наш файл
        end;
        base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Отключаемся);
        base.FTP.Disconnect;
    except base.Memo.Lines.Add(datetostr(date)+timetostr(time)+ Ошибка соеденения); end;
ftp_list.Free;
end;


Пояснения:
1 base.Memo - используется как лог
2 процедура сканирует указаную папку на жеством диске и если находятся файлы по маске, то процедура загружает все файлы на фтп
А вы какими компонентами пользуетесь ?
Если у вас класс клиента TFtpClient из библиотеки Francois PIETTE, то там просто в евентах надо найти OnProgress и для него написать чтонибудь типа такого:


procedure TfmFTPProgress.FtpClient1Progress(Sender: TObject;
  Count: Integer; var Abort: Boolean);
begin
  ProgressBar1.Position := Count;
  ProgressBar1.Repaint;
  Label3.Caption := IntToStr(Count);
  Label3.Repaint;
end;



При условии что вы узнали размер файла и установили ProgressBar1.Max равное этому размеру до того как начали передачу или прием.
У IdFTP есть события, которые генерируются при работе Put и Get - используйте их для вывода этой информации (не помню точные имена, ключевое слово - Work).
Я пользуюсь indy 10 и delphi studio 2006, у IdFTP есть событие OnWork. Да я могу определить размер файла в байтах - это будет максимум, но вопрос в том, как отследить уже переданное количество байт?
Может быть поделится кто-нибудь кодом?
ОТвечу сам себе, в собитии OnWork следующий код:

procedure Tbase.FTPWork(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Integer);
begin
base.ProgressBar1.Position:=aworkcount;
base.ProgressBar1.Refresh;
base.ProgressBar1.Repaint;
end;


До закачивания\скачивания файла нужно определяю размер файла и выставить его в ProgressBar, как максимальное значение.

При закачивании файла с локального диска размер можно определить такой функцией(опубликова была на вашем сайте):
function tbase.GetFileSize(FileName: String): Integer;
var
  FS: TFileStream;
begin
  try
    FS := TFileStream.Create(Filename, fmOpenRead);
  except
    Result := -1;
  end;
  if Result <> -1 then Result := FS.Size;
  FS.Free;
end;


При скачивении файла, необходимо запросить размер файла с фтп(если размер =-1 то такого файла нет):
base.ProgressBar1.Max:=FTP.Size(<название файла>)

Надеюсь кому-нибудь это поможет сократить время на поиски.