Скорость загрузки Indy - PullRequest
2 голосов
/ 29 ноября 2011

Как из этого кода я могу вернуть скорость загрузки?

procedure TForm1.Button1Click(Sender: TObject);
begin

ftp.Host := 'domain';
ftp.Username := 'username';
ftp.password := 'password';
ftp.Connect;
ftp.Put('random-filename.ext'); //This is where it should grab only the latest file
//label1.caption := 'Download Speed: %s';  
ftp.Quit;
ftp.Disconnect;

end;

Нужен ли таймер?

Спасибо.

Ответы [ 4 ]

4 голосов
/ 29 ноября 2011

Если вы используете компонент TIdFTP, то для расчета скорости передачи необходимо использовать события OnWork, OnWorkBegin и OnWorkEnd.

2 голосов
/ 29 ноября 2011

Событие TIdFTP.OnWorkBegin сообщит вам, сколько байтов будет отправлено, а событие TIdFTP.OnWork сообщит вам, сколько байтов было отправлено до сих пор во время передачи. Исходя из того, сколько времени проходит между отдельными OnWork событиями запуска и разницей в передаваемых байтах между каждым, вы можете вычислить скорость.

1 голос
/ 24 сентября 2015

Класс TTimer не требуется, только события OnWorkBegin, OnWork и OnWorkEnd компонента Indy.

Вы можете сделать то же самое, как показано ниже, но я рекомендую помещать код FTP в поток и обновлять пользовательский интерфейс с помощью метода Synchronizeдля лучшей производительности.

interface 

uses
  // ...
  Windows;

type
  TForm1 = class(TForm)
  private
    startWriteTime : DWord;
    byteToWrite : Int64;

    procedure ftp_OnWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
    procedure ftp_OnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
    procedure ftp_OnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);

    procedure displayWriteSpeed(byteWritten: Int64);
end;

implementation

uses
  // ...
  SysUtils;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ftp.OnWorkBegin := ftp_OnWorkBegin;
  ftp.OnWork := ftp_OnWork;
  ftp.OnWorkEnd := ftp_OnWorkEnd;
  // ...
  ftp.Connect;
  // ...
end;

procedure TForm1.ftp_OnWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
  if AWorkMode = wmWrite then
  begin
    byteToWrite := AWorkCountMax;
    startWriteTime := Windows.GetTickCount;
    displayWriteSpeed(-1);
  end;
end;

procedure TForm1.ftp_OnWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
  if AWorkMode = wmWrite then
  begin
    displayWriteSpeed(AWorkCount);
  end;
end;

procedure TForm1.ftp_OnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
  if AWorkMode = wmWrite then
  begin
    displayWriteSpeed(byteToWrite);
  end;
end;

procedure TForm1.displayWriteSpeed(byteWritten: Int64);
var
  elapsedMilliSeconds,  elapsedSeconds : Dword;
  speedBytesPerSeconds : Int64;
begin
  if byteWritten < 0 then
  begin
    {writeSpeedLabel.}Caption := 'upload speed: ?';
    Exit;
  end;

  elapsedMilliSeconds := Windows.GetTickCount - startWriteTime;
  elapsedSeconds := elapsedMilliSeconds div 1000;
  speedBytesPerSeconds := byteWritten div elapsedSeconds;
  {writeSpeedLabel.}Caption := SysUtils.Format('upload speed: %d b/s', [speedBytesPerSeconds ] );
end;
0 голосов
/ 30 ноября 2011

Для части таймера:

Вы можете использовать встроенные функции и глобальные переменные:

var
  start, stop, elapsed: TDateTime;
  ielapsed: Integer;

// Start the timer
start := Now;
// Stop the timer
stop := Now;
elapsed := stop - start;
// Convert to milliseconds
ielapsed := round(elapsed * 60 * 60 * 24 * 1000);

Поскольку функция Windows API GetTickCount уже в миллисекундахЭто простой способ подсчитать прошедшее время, но только в Windows 2000 +:

var
  start, stop, elapsed: DWORD;

start := GetTickCount;
stop := GetTickCount;

if (stop > start) then
begin
  elapsed := stop - start;
end
else
begin
  // Handle overflow
  elapsed := MAXDWORD - start + stop;
end;
...