/// <summary> /// SFTP文件上传下载 /// </summary> public class SFtp { /// <summary> /// http://www.example-code.com/csharp/sftp_readDir.asp /// </summary> Chilkat.SFtp sftp = new Chilkat.SFtp(); /// <summary> /// 连接 /// </summary> /// <returns></returns> public bool Connection() { //尝试连接2次 int tryCount = 0; while (tryCount++ < 2) { bool conn = TryConnection(); if (conn == true) return true; } return false; } /// <summary> /// 尝试连接 /// </summary> /// <returns></returns> private bool TryConnection() { bool success = false; sftp.ConnectTimeoutMs = 1000; sftp.IdleTimeoutMs = 5000; // Any string automatically begins a fully-functional 30-day trial. success = sftp.UnlockComponent(AppConfig.GetValueByKey("sftpKey")); if (success != true) { LogHelper.Write("SFTP-----------注册失败!\r\n{0}", sftp.LastErrorText); return false; } // Connect to the SSH server. // The standard SSH port = 22 // The hostname may be a hostname or IP address. string hostname = AppConfig.GetValueByKey("host"); int port = Convert.ToInt32(AppConfig.GetValueByKey("port")); success = sftp.Connect(hostname, port); if (success != true) { LogHelper.Write("SFTP-----------服务拒绝连接!\r\n{0}", sftp.LastErrorText); return false; } string username = AppConfig.GetValueByKey("username"); string pwd = AppConfig.GetValueByKey("pwd"); success = sftp.AuthenticatePw(username, pwd); if (success != true) { LogHelper.Write("SFTP-----------服务名或密码错误!\r\n{0}", sftp.LastErrorText); return false; } //After authenticating, the SFTP subsystem must be initialized: success = sftp.InitializeSftp(); if (success != true) { LogHelper.Write("SFTP----------- initialized Faile!\r\n{0}", sftp.LastErrorText); return false; } return success; } /// <summary> /// 创建目录 /// </summary> /// <param name="folder">要创建的远程目录 eg:./aa/cc</param> public void MakeDirectory(string folder) { try { sftp.CreateDir(folder); } catch (Exception ex) { Log.LogHelper.Write("SFTP创建目录------------------ {0}", ex.ToString()); } } /// <summary> /// 断开连接 /// </summary> public void DisConnection() { try { if (sftp != null) { sftp.Disconnect(); } } catch (Exception ex) { Log.LogHelper.Write("SFTP关闭连接------------------ {0}", ex.ToString()); } } /// <summary> /// 下载文件 /// </summary> /// <param name="remoteFilePath">远程文件路径 eg: ./aa/hamlet.xml</param> /// <param name="localFilePath">本地文件路径 eg: c:/temp/hamlet.xml</param> public bool DownFile(string remoteFilePath, string localFilePath) { bool success = false; // Note: The remote filepath may be an absolute filepath, // a relative filepath, or simply a filename. // Relative filepaths are always relative to the home directory // of the SFTP/SSH user account. There is no such thing // as "current remote directory" in the SFTP protocol. // A filename with no path implies that the file is located // in the SFTP user account's home directory. success = sftp.DownloadFileByName(remoteFilePath, localFilePath); if (success != true) { LogHelper.Write("SFTP-----------文件下载\r\n{0}", sftp.LastErrorText); } return success; } /// <summary> /// 下载文件 /// </summary> /// <param name="remoteFilePath">远程文件路径 eg: ./aa/hamlet.xml</param> private void Rename(string remoteFilePath) { bool success = false; // Rename the file or directory: success = sftp.RenameFileOrDir(remoteFilePath + ".bak", remoteFilePath); if (success != true) { LogHelper.Write("SFTP-----------文件改名称\r\n名称是否已存在或{0}", sftp.LastErrorText); } } /// <summary> /// 下载文件 /// </summary> /// <param name="remoteFilePath">远程文件路径 eg: ./aa/hamlet.xml</param> /// <param name="localFilePath">本地文件路径 eg: c:/temp/hamlet.xml</param> /// <param name="remoteBakFilePath">远程备份目录 eg: ./ddd</param> public bool DownFileAndBak(string remoteFilePath, string localFilePath,string remoteBakFilePath) { //下载 if (DownFile(remoteFilePath, localFilePath)) { //备份:上传 if (UpLoadFile(remoteBakFilePath, localFilePath,false)) { //删除原件 if (DeleteFile(remoteFilePath)) { return true; } } } return false; } /// <summary> /// 文件上传 /// </summary> /// <param name="remoteFilePath">远程文件路径 eg: ./aa/hamlet.xml</param> /// <param name="localFilePath">本地文件路径 eg: c:/temp/hamlet.xml</param> /// <returns></returns> public bool UpLoadFile(string remoteFilePath, string localFilePath, bool bAppendBak) { bool success = false; string tmpRemoteFilePath = remoteFilePath; if (bAppendBak) { tmpRemoteFilePath += ".bak"; } success = sftp.UploadFileByName(tmpRemoteFilePath, localFilePath); if (success != true) { LogHelper.Write("SFTP-----------上传文件\r\n{0}", sftp.LastErrorText); } if (success && bAppendBak) { Rename(remoteFilePath); } return success; } /// <summary> /// 删除远程文件 /// </summary> /// <param name="remoteFilePath">远程文件路径 eg: ./aa/hamlet.xml</param> /// <returns></returns> public bool DeleteFile(string remoteFilePath) { // Delete a file on the server: bool success = false; success = sftp.RemoveFile(remoteFilePath); if (success != true) { LogHelper.Write("SFTP-----------删除文件\r\n{0}", sftp.LastErrorText); } return success; } /// <summary> /// 删除远程文件 /// </summary> /// <param name="remoteFilePath">远程目录路径 eg: ./ddd</param> /// <returns></returns> public bool DeleteDir(string remoteDirPath) { // Delete a file on the server: bool success = false; success = sftp.RemoveDir(remoteDirPath); if (success != true) { LogHelper.Write("SFTP-----------删除文件\r\n{0}", sftp.LastErrorText); } return success; } /// <summary> /// 读取远程目录内所有文件 /// </summary> /// <param name="remoteDirName">远程文件路径 eg: ./ddd</param> /// <returns></returns> private List<string> GetAllFileNames(string remoteDirName) { List<string> list = new List<string>(); bool success = false; string handle; handle = sftp.OpenDir(remoteDirName); if (handle == null) { LogHelper.Write("SFTP-----------读取目录所有文件\r\n{0}", sftp.LastErrorText); return null; } // Download the directory listing: Chilkat.SFtpDir dirListing = null; dirListing = sftp.ReadDir(handle); if (dirListing == null) { LogHelper.Write("SFTP-----------读取目录所有文件\r\n{0}", sftp.LastErrorText); return null; } int n = dirListing.NumFilesAndDirs; for (int i = 0; i <= n - 1; i++) { Chilkat.SFtpFile fileObj = null; fileObj = dirListing.GetFileObject(i); switch (fileObj.FileType) { case "directory": break; case "regular": if (System.Text.RegularExpressions.Regex.IsMatch(fileObj.Filename, AppConfig.GetValueByKey("ext"))) list.Add(fileObj.Filename); break; } } // Close the directory success = sftp.CloseHandle(handle); if (success != true) { LogHelper.Write("SFTP-----------读取目录所有文件\r\n{0}", sftp.LastErrorText); return null; } return list; } /// <summary> /// 收取指定文件夹下所有文件 /// </summary> /// <param name="remoteDirName">远程目录路径 eg: ./ddd</param> /// <param name="localDirName">本地目录路径 eg: D:/ddd</param> /// <param name="remoteBakFilePath">远程备份目录 eg: ./ddd</param> public List<string> DownAllFilesByDirName(string remoteDirName,string localDirName,string remoteBakFilePath = null) { List<string> list = GetAllFileNames(remoteDirName); List<string> lsRetuen = new List<string>(); if (list != null) { foreach (string s in list) { if (string.IsNullOrEmpty("DownFileAndBak")) { if (DownFile(remoteDirName + "/" + s, localDirName + "/" + s)) { lsRetuen.Add(s); } } else { if (DownFileAndBak(remoteDirName + "/" + s, localDirName + "/" + s, remoteBakFilePath + "/" + s)) { lsRetuen.Add(s); } } } } return lsRetuen; } }