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 можно получить детальную информацию о каталогах и файлах.
Комментариев нет:
Отправить комментарий