Indy上传速度

时间:2011-11-29 13:52:07

标签: delphi indy

从这段代码中,我该如何返回上传速度?

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 个答案:

答案 0 :(得分:4)

假设您使用的是TIdFTP组件,则必须使用OnWorkOnWorkBeginOnWorkEnd事件来计算传输速率。

答案 1 :(得分:2)

TIdFTP.OnWorkBegin事件将告诉您将发送多少字节,TIdFTP.OnWork事件将告诉您在传输过程中到目前为止已发送了多少字节。根据单个OnWork事件触发之间经过的时间和每个事件之间传输字节的差异,您可以计算速度。

答案 2 :(得分:1)

不需要TTimer类,只需要Indy组件OnWorkBegin,OnWork和OnWorkEnd事件。

您可以执行以下操作,但我建议您将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;

答案 3 :(得分:0)

对于计时器部分:

您可以使用内置函数和全局变量:

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;