SFTP (SSH File Transfer Protocol) - протокол прикладного уровня, предназначенный для выполнения различных операций с файлами через безопасное соединение. В отличие от FTP, он шифрует команды и данные, предотвращая открытую передачу конфиденциальной информации по сети. Давайте посмотрим, как из программы на Delphi загрузить файл на SFTP-сервер и скачать его.
Для работы с SFTP-сервером я воспользуюсь компонентой TclSFtp из библиотеки Clever Internet Suite. Она реализует поддержку протокола SSH FTP и позволяет через него работать с файлами и каталогами.
Для работы с SFTP-сервером я воспользуюсь компонентой TclSFtp из библиотеки Clever Internet Suite. Она реализует поддержку протокола SSH FTP и позволяет через него работать с файлами и каталогами.
program sftp;
{$APPTYPE CONSOLE}
uses
System.Classes, System.SysUtils, clSFtp, clSFtpHelper;
procedure Test(const sLocalFile, sFtpDir: String);
var
sftp: TclSFtp;
sFileName: String;
begin
sFileName := ExtractFileName(sLocalFile);
sftp := TclSFtp.Create(nil);
try
sftp.CharSet := 'UTF-8';
// подключение к SFTP-серверу
sftp.Server := 'localhost';
sftp.Port := 22;
sftp.UserName := 'BlackCat';
sftp.Password := '123';
sftp.Open;
if sftp.DirectoryExists(sFtpDir) then
begin
// выбираем каталог на SFTP-сервере
sftp.ChangeCurrentDir(sFtpDir);
// загружаем файл на SFTP-сервер
sftp.PutFile(sLocalFile, sFileName);
// загружаем файл с SFTP-сервера
sftp.GetFile(sFileName, 'c:\temp\' + sFileName);
end;
finally
sftp.Free
end;
end;
begin
try
Test('d:\MSSQL\Backup\xyz.bak', 'backup');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.
Как видите – все очень просто. Небольшие пояснения и советы:
- Процедура Test собрана из кусков моего класса и для упрощения очищена от обработки ошибок.
- Строка 16. CharSet = 'UTF-8' позволит избежать проблем с национальными символами.
- Строка 25. К сожалению, метод ChangeCurrentDir в 28-й строке не вызывает ошибку если на SFTP-сервере не существует нужный каталог. При этом у TclSFtp нет метода для проверки наличия каталога. Можно, конечно, использовать метод FileExists (он работает и для каталогов), но это может привести к ошибке, если пользователь укажет в качестве каталога имя файла. В таком случае, мне кажется, что будет более корректно сделать проверку отлавливая ошибку при вызове метода получения списка каталогов и файлов
procedure GetList(AList: TStrings; const AFilePath: string = ''; ADetails: Boolean = True);
Но мне это показалось не правильным, и я, чтобы добраться к приватным методам TclSFtp, сделал для него class helper с функцией DirectoryExistsunit clSFtpHelper; interface uses System.SysUtils, clSFtp, clTranslator, clSFtpUtils; type TclSFtpHelper = class helper for TclSFtp function DirectoryExists(const AFilePath: string): Boolean; end; implementation { TclSFtpHelper } function TclSFtpHelper.DirectoryExists(const AFilePath: string): Boolean; begin if AFilePath.isEmpty then Result := True else with Self do try SendOPENDIR(TclTranslator.GetBytes(GetFullPath(AFilePath), CharSet)); Result := (FResponseType = SSH_FXP_HANDLE) and (FStatusCode = 0); except Result := False; end; end; end. - Методы PutFile и GetFile могут работать с потоками и загружать файлы по частям, что позволяет реализовать проверку их сигнатур или докачку.
- Используя событие OnVerifyServer
TclVerifySshPeerEvent = procedure(Sender: TObject; const AHost, AKeyType, AFingerPrint, AHostKey: string; var AVerified: Boolean) of object;
можно проверить информацию об открытом ключе SFTP-сервера. - Используя событие OnProgress
TclProgressEvent = procedure(Sender: TObject; ABytesProceed, ATotalBytes: Int64) of object;
можно следить за процессом загрузки файла. - Комбинируя событие OnDirectoryListing
TclSFtpDirectoryListingEvent = procedure(Sender: TObject; const AFileName: string; AFileAttrs: TclSFtpFileAttrs) of object;
и вызов методов DirectoryListing/GetList можно получить детальную информацию о каталогах и файлах.
Комментариев нет:
Отправить комментарий