using System; using System.IO; using Renci.SshNet; using Renci.SshNet.Sftp; using System.Collections.Generic; namespace SFTPUtils { public class SftpClientWithKey { private SftpClient _sftpClient; private readonly string _host; private readonly int _port; private readonly string _username; private readonly string _privateKeyPath; /// /// 初始化 SFTP 客户端 /// /// SFTP 服务器地址 /// 端口(默认22) /// 用户名 /// OpenSSH 格式私钥文件路径 public SftpClientWithKey(string host, int port, string username, string privateKeyPath) { _host = host; _port = port; _username = username; _privateKeyPath = privateKeyPath; } /// /// 连接到 SFTP 服务器 /// public void Connect() { try { if (_sftpClient != null && _sftpClient.IsConnected) { return; } var keyFiles = new[] { new PrivateKeyFile(_privateKeyPath) }; var connectionInfo = new ConnectionInfo(_host, _port, _username, new PrivateKeyAuthenticationMethod(_username, keyFiles)); _sftpClient = new SftpClient(connectionInfo); _sftpClient.Connect(); } catch (Exception ex) { throw new Exception($"SFTP 连接失败: {ex.Message}", ex); } } /// /// 断开连接 /// public void Disconnect() { if (_sftpClient != null && _sftpClient.IsConnected) { _sftpClient.Disconnect(); } } /// /// 上传文件到 SFTP 服务器 /// /// 本地文件路径 /// 远程目录 /// 远程文件名(可选,如果为空则使用本地文件名) /// 上传成功返回 true public bool UploadFile(string localFilePath, string remoteDirectory, string remoteFileName = null) { if (!File.Exists(localFilePath)) { throw new FileNotFoundException("本地文件不存在", localFilePath); } Connect(); try { // 确保远程目录存在 CreateRemoteDirectory(remoteDirectory); // 确定远程文件名 string finalRemoteFileName = string.IsNullOrEmpty(remoteFileName) ? Path.GetFileName(localFilePath) : remoteFileName; string remoteFilePath = $"{remoteDirectory.TrimEnd('/')}/{finalRemoteFileName}"; using (var fileStream = new FileStream(localFilePath, FileMode.Open)) { _sftpClient.UploadFile(fileStream, remoteFilePath); } return true; } catch (Exception ex) { throw new Exception($"文件上传失败: {ex.Message}", ex); } } /// /// 创建远程目录(如果不存在) /// /// 远程目录路径 private void CreateRemoteDirectory(string remoteDirectory) { try { var directories = remoteDirectory.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); string currentPath = string.Empty; foreach (var directory in directories) { currentPath += "/" + directory; if (!_sftpClient.Exists(currentPath)) { _sftpClient.CreateDirectory(currentPath); } } } catch (Exception ex) { throw new Exception($"创建远程目录失败: {ex.Message}", ex); } } /// /// 检查文件是否存在 /// /// 远程文件路径 /// 存在返回 true public bool FileExists(string remoteFilePath) { Connect(); return _sftpClient.Exists(remoteFilePath); } /// /// 列出远程目录中的文件 /// /// 远程目录 /// 文件列表 public IEnumerable ListFiles(string remoteDirectory) { Connect(); return _sftpClient.ListDirectory(remoteDirectory); } /// /// 删除远程文件 /// /// 远程文件路径 /// 删除成功返回 true public bool DeleteFile(string remoteFilePath) { Connect(); if (_sftpClient.Exists(remoteFilePath)) { _sftpClient.DeleteFile(remoteFilePath); return true; } return false; } /// /// 释放资源 /// public void Dispose() { Disconnect(); _sftpClient?.Dispose(); } } }