⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpobjunit.pas

📁 script language
💻 PAS
字号:
unit ftpobjunit;

interface

uses idftp, classes, sysutils, idcomponent, IdLogDebug;

type
  TFtpClientObject = class
  private
    idFtp1: TIDFtp;
    IdLogDebug: TIdLogDebug;
    AbortTransfer: Boolean;
    TransferringData: Boolean;
    BytesToTransfer: LongWord;
    AverageSpeed: Double;
    STime: TDateTime;
    ContatoreFind: integer;
    procedure IdFTP1Status(axSender: TObject; const axStatus: TIdStatus;
      const asStatusText: string);
    procedure IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
    procedure IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    procedure IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
    function GetNameFromLine(Line: string; var IsDirectory: Boolean): string;
    procedure IdFTP1Disconnected(Sender: TObject);
    procedure IdFTP1Connected(Sender: TObject);
    procedure CutFirstWord(var Stringa: string);
    procedure WordPos(Stringa: string; var Position, Size: integer);
    function GetSizeFromLine(Line: string): integer;
    procedure IdLogDebug1LogItem(ASender: TComponent; var AText: string);
    function GetLogTarget: TIdLogDebugTarget;
    procedure SetLogTarget(Value: TIdLogDebugTarget);
    function GetLogFile: string;
    procedure SetLogFile(Value: string);
  public
    Host, Username, Password, DefaultDir, CurrentDir, Status: string;
    MaskPassword: Boolean;
    DirectoryFilter, LastError, LastResponse: string;
    DirectoryList: TStringList;
    procedure Execute(Cmd: string; out rets: integer);
    function GetFileProperties(Filename: string; var IsDirectory: Boolean; var Size: Integer): string;
    function DeleteFile(Name: string): string;
    function RemoveDir(Name: string): string;
    function Download(SourceFile, DestFile: string): string;
    function Upload(SourceFile, DestFile: string): string;
    function Connect: string;
    function DisConnect: string;
    function ChangeDir(Dirname: string): string;
    function MakeDir(Name: string): string;
    function FindFirst(Specifier: string; var Filename: string; var IsDirectory: Boolean; var Size: integer): string;
    function FindNext(var FileName: string; var IsDirectory: Boolean; var Size: integer): string;
    function FindClose: string;
    procedure Abort;
    constructor Create;
    destructor Destroy; override;
    property LogType: TIdLogDebugTarget read GetLogTarget write SetLogTarget;
    property LogFile: string read GetLogFile write SetLogFile;
  end;

implementation

uses
  Dialogs;

function TFtpClientObject.GetLogFile: string;
begin
  result := idlogdebug.Filename;
end;

procedure TFtpClientObject.SetLogFile(Value: string);
begin
  if Value <> '' then
  begin
    idlogdebug.Filename := Value;
    idlogdebug.Target := ltFile;
  end;
end;

function TFtpClientObject.GetLogTarget: TIdLogDebugTarget;
begin
  result := idlogdebug.Target;
end;

procedure TFtpClientObject.SetLogTarget(Value: TIdLogDebugTarget);
begin
  idlogdebug.Target := Value;
end;

procedure TFtpClientObject.IdLogDebug1LogItem(ASender: TComponent;
  var AText: string);
var
  inizio: integer;
const
  INVIO_PWD = 'Sent: pass ';
begin
  if MaskPassword then
  begin
    Inizio := Pos(INVIO_PWD, AText);
    if Inizio > 0 then
    begin
      Atext := Copy(AText, 0, Inizio - 1) + INVIO_PWD + '*****<EOL>';
    end;
  end;
  LastResponse := AText;
end;

procedure TFtpClientObject.Execute(Cmd: string; out rets: integer);
begin
  rets := idftp1.SendCmd(cmd);
end;

procedure TFtpClientObject.CutFirstWord(var Stringa: string);
var
  x, s: integer;
begin
  WordPos(Stringa, x, s);
  Stringa := Trim(Copy(Stringa, x + s, Length(Stringa)));
end;

procedure TFtpClientObject.WordPos(Stringa: string; var Position, Size: integer);
var
  Str: string;
begin
  position := 1;
  Str := Stringa;

  while Str[1] = ' ' do
  begin
    System.Delete(str, 1, 1);
    Inc(Position);
  end;

  Size := Pos(' ', Str) - 1;
end;

procedure TFtpClientObject.IdFTP1Status(axSender: TObject; const axStatus: TIdStatus;
  const asStatusText: string);
begin
  Status := asStatusText;
end;

procedure TFtpClientObject.IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
begin
  TransferringData := true;
  AbortTransfer := false;
  STime := Now;
  AverageSpeed := 0;
end;

procedure TFtpClientObject.IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
  Status := 'Transfer complete.';
  BytesToTransfer := 0;
  TransferringData := false;
  AverageSpeed := 0;
end;

procedure TFtpClientObject.IdFTP1Disconnected(Sender: TObject);
begin
  Status := 'Disconnected.';
end;

procedure TFtpClientObject.IdFTP1Connected(Sender: TObject);
begin
  Status := 'Connected.';
end;

procedure TFtpClientObject.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
var
  S: string;
  TotalTime: TDateTime;
  H, M, Sec, MS: Word;
  DLTime: Double;
begin
  TotalTime := Now - STime;
  DecodeTime(TotalTime, H, M, Sec, MS);
  Sec := Sec + M * 60 + H * 3600;
  DLTime := Sec + MS / 1000;
  if DLTime > 0 then
    AverageSpeed := {(AverageSpeed + }(AWorkCount / 1024) / DLTime {) / 2};

  S := FormatFloat('0.00 KB/s', AverageSpeed);
  case AWorkMode of
    wmRead: status := 'Download speed ' + S;
    wmWrite: status := 'Upload speed ' + S;
  end;

  if AbortTransfer then
    IdFTP1.Abort;

  AbortTransfer := false;
end;

function TFtpClientObject.GetSizeFromLine(Line: string): integer;
var
  str: string;
  x, s: integer;
begin
  CutFirstWord(Line);
  CutFirstWord(Line);

  WordPos(Line, x, s);
  str := Copy(Line, x, s);
  try
    Result := StrToInt(str);
  except
    Result := -1;
  end;
end;

function TFtpClientObject.GetFileProperties(Filename: string; var IsDirectory: Boolean; var Size: Integer): string;
var
  i: Integer;
  strName, Line: string;
  IsDir, FileExists: Boolean;
begin
  Size := 0;
  IsDirectory := false;
  FileExists := False;

  for i := 0 to DirectoryList.Count - 1 do
  begin
    Line := DirectoryList[i];
    StrName := GetNameFromLine(Line, IsDir);
    if strName = FileName then
    begin
      FileExists := true;
      Size := GetSizeFromLine(Line);
      IsDirectory := isdir;
    end;
  end;

  if FileExists then
    Result := ''
  else
    Result := 'File does not exists';

  LastError := Result;
end;

function TFtpClientObject.GetNameFromLine(Line: string; var IsDirectory: Boolean): string;
var
  i: Integer;
  DosListing: Boolean;
begin
  IsDirectory := Line[1] = 'd';
  DosListing := false;
  for i := 0 to 7 do
  begin
    if (i = 2) and not IsDirectory then
    begin
      IsDirectory := Copy(Line, 1, Pos(' ', Line) - 1) = '<DIR>';
      if not IsDirectory then
        DosListing := Line[1] in ['0'..'9']
      else
        DosListing := true;
    end;
    System.Delete(Line, 1, Pos(' ', Line));
    while Line[1] = ' ' do
      System.Delete(Line, 1, 1);
    if DosListing and (i = 2) then
      break;
  end;
  Result := Line;
end;

constructor TFtpClientObject.Create;
begin
  inherited Create;
  maskPassword := True;
  idFTP1 := TIdFtp.Create(nil);
  idftp1.Name := 'myidftp';
  DefaultDir := '/';
  AverageSpeed := 0;
  AbortTransfer := False;
  TransferringData := False;
  BytesToTransfer := 0;

  DirectoryList := TStringList.Create;
  DirectoryFilter := '';

  idftp1.OnDisconnected := IdFTP1Disconnected;
  idftp1.OnConnected := IdFTP1Connected;
  idftp1.OnStatus := IdFTP1Status;
  idftp1.OnWork := IdFTP1Work;
  idftp1.OnWorkEnd := IdFTP1WorkEnd;
  idftp1.OnWorkBegin := IdFTP1WorkBegin;

  IdLogDebug := TIdLogDebug.Create(nil);
  IdLogdebug.OnLogItem := IdLogDebug1LogItem;
  idftp1.Intercept := IdLogDebug;
  idftp1.InterceptEnabled := true;
  IdLogDebug.Target := ltDebugOutput;
end;

destructor TFtpClientObject.Destroy;
begin
  idlogdebug.Free;
  DirectoryList.Clear;
  DirectoryList.Free;
  idFtp1.Free;
  inherited Destroy;
end;

function TFtpClientObject.Connect: string;
begin
  IdLogDebug.Active := true;
  try
    if IdFTP1.Connected then
    begin
      if TransferringData then
        IdFTP1.Abort;
      IdFTP1.Quit;
    end
    else
    begin
      IdFTP1.User := Self.UserName;
      IdFTP1.Password := Self.Password;
      IdFTP1.Host := Self.Host;
      IdFTP1.Connect;
      ChangeDir(DefaultDir);
    end;
  except
    on e: exception do
    begin
      Result := e.message;
    end;
  end;

  LastError := Result;
end;

function TFtpClientObject.DisConnect: string;
begin
  try
    if IdFTP1.Connected then
    begin
      if TransferringData then
        IdFTP1.Abort;
      IdFTP1.Quit;
      idftp1.Disconnect
    end;
  except
    on e: exception do
    begin
      Result := e.message;
    end;
  end;
  LastError := Result;
end;

function TFtpClientObject.ChangeDir(DirName: string): string;
begin
  try
    IdFTP1.ChangeDir(DirName);
    IdFTP1.TransferType := ftASCII;
    CurrentDir := IdFTP1.RetrieveCurrentDir;
    IdFTP1.List(DirectoryList, DirectoryFilter);
  except
    on e: exception do
    begin
      Result := e.message;
    end;
  end;
  LastError := Result;
end;

function TFtpClientObject.Download(SourceFile, DestFile: string): string;
begin
  if not IdFTP1.Connected then
  begin
    Result := 'not connected';
    LastError := Result;
    exit;
  end;

  try
    IdFTP1.TransferType := ftBinary;
    BytesToTransfer := IdFTP1.Size(SourceFile);
    IdFTP1.Get(SourceFile, DestFile, true);
  except
    on e: exception do
    begin
      Result := e.message;
    end;
  end;
  LastError := Result;
end;

function TFtpClientObject.Upload(SourceFile, DestFile: string): string;
var
  Done: boolean;
  RetryNumber: integer;
begin
  if not IdFTP1.Connected then
  begin
    Result := 'not connected';
    LastError := Result;
    exit;
  end;

  RetryNumber := 5;
  Done := False;
  try
    IdFTP1.TransferType := ftBinary;
    while not Done do
    try
      IdFTP1.Put(SourceFile, DestFile);
      Done := True;
    except
      Sleep(1000);
      Dec(RetryNumber);
      if RetryNumber = 0 then
        raise;
    end;
    ChangeDir(idftp1.RetrieveCurrentDir);
  except
    on e: exception do
    begin
      Result := e.message;
    end;
  end;
  LastError := Result;
end;

function TFtpClientObject.RemoveDir(name: string): string;
begin
  if not IdFTP1.Connected then
  begin
    Result := 'not connected';
    LastError := Result;
    exit;
  end;

  try
    idftp1.RemoveDir(Name);
    ChangeDir(idftp1.RetrieveCurrentDir);
  except
    on e: exception do
    begin
      Result := e.message;
    end;
  end;
  LastError := Result;
end;

function TFtpClientObject.MakeDir(name: string): string;
begin
  if not IdFTP1.Connected then
  begin
    Result := 'not connected';
    LastError := Result;
    exit;
  end;

  try
    IdFTP1.MakeDir(Name);
    ChangeDir(idftp1.RetrieveCurrentDir);
  except
    on e: exception do
    begin
      Result := e.message;
      LastError := Result;
    end;
  end;
end;

function TFtpClientObject.DeleteFile(name: string): string;
begin
  if not IdFTP1.Connected then
  begin
    Result := 'not connected';
    LastError := Result;
    exit;
  end;

  try
    idftp1.Delete(Name);
    // se il filtro 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -