using Renci.SshNet;
using Renci.SshNet.Sftp;
using System;
using System.IO;
using System.Collections;
using BaseLibrary.ExecutionResults;
namespace BaseLibrary.SSH
{
/// <summary>
/// SFTP操作类
/// </summary>
public class SFTPHelper
{
#region 字段或属性
private SftpClient sftp;
/// <summary>
/// SFTP连接状态
/// </summary>
public bool Connected { get { return sftp.IsConnected; } }
#endregion
#region 构造
/// <summary>
/// 构造
/// </summary>
/// <param name="ip">IP</param>
/// <param name="port">端口</param>
/// <param name="user">用户名</param>
/// <param name="pwd">密码</param>
public SFTPHelper(string ip, string port, string user, string pwd)
{
sftp = new SftpClient(ip, Int32.Parse(port), user, pwd);
}
#endregion
#region 连接SFTP
/// <summary>
/// 连接SFTP
/// </summary>
/// <returns>true成功</returns>
public bool Connect()
{
try
{
if (!Connected)
{
sftp.Connect();
}
return true;
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("连接SFTP失败,原因:{0}", ex.Message));
throw new Exception(string.Format("连接SFTP失败,原因:{0}", ex.Message));
}
}
#endregion
#region 断开SFTP
/// <summary>
/// 断开SFTP
/// </summary>
public void Disconnect()
{
try
{
if (sftp != null && Connected)
{
sftp.Disconnect();
}
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("断开SFTP失败,原因:{0}", ex.Message));
throw new Exception(string.Format("断开SFTP失败,原因:{0}", ex.Message));
}
}
#endregion
#region SFTP上传文件
/// <summary>
/// SFTP上传文件
/// </summary>
/// <param name="localPath">本地路径</param>
/// <param name="remotePath">远程路径</param>
public void Put(string localPath, string remotePath)
{
try
{
using (var file = File.OpenRead(localPath))
{
Connect();
sftp.UploadFile(file, remotePath);
Disconnect();
}
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("SFTP文件上传失败,原因:{0}", ex.Message));
throw new Exception(string.Format("SFTP文件上传失败,原因:{0}", ex.Message));
}
}
#endregion
#region SFTP下载
/// <summary>
/// SFTP获取文件
/// </summary>
/// <param name="remotePath">远程路径</param>
/// <param name="localPath">本地路径</param>
public ExecutionResult Download(string remotePath, string localPath)
{
ExecutionResult exeResult = new ExecutionResult();
exeResult.Message = string.Empty;
try
{
Connect();
if (sftp.Exists(remotePath))
{
using (var stream = File.Open(localPath, FileMode.OpenOrCreate))
{
sftp.DownloadFile(remotePath, stream);
}
exeResult.Status = true;
return exeResult;
}
else
{
exeResult.Message = $"Not exist [{remotePath}] on remote SFTP server";
exeResult.Status = false;
return exeResult;
}
}
catch (Exception ex)
{
Disconnect();
exeResult.Message = ex.Message;
exeResult.Status = false;
return exeResult;
}
}
#endregion
#region SFTP获取文件
/// <summary>
/// SFTP获取文件
/// </summary>
/// <param name="remotePath">远程路径</param>
/// <param name="localPath">本地路径</param>
public void Get(string remotePath, string localPath)
{
try
{
Connect();
var byt = sftp.ReadAllBytes(remotePath);
//Disconnect();
File.WriteAllBytes(localPath, byt);
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("SFTP文件获取失败,原因:{0}", ex.Message));
Disconnect();
throw new Exception(string.Format("SFTP文件获取失败,原因:{0}", ex.Message));
}
}
#endregion
#region SFTP获取文件
/// <summary> 只能读取二层,待修改
/// SFTP获取文件
/// </summary>
/// <param name="remotePath">远程路径</param>
/// <param name="localPath">本地路径</param>
public ExecutionResult GetFolder(string remotePath, string localPath)
{
ExecutionResult exeResult = new ExecutionResult();
exeResult.Message = "get the whole folder successfully!";
try
{
Connect();
var files = sftp.ListDirectory(remotePath);
foreach (var file in files)
{
try
{
string name = file.Name;
if (file.IsDirectory)
{
string loacalFolder = localPath + $"\\{file.Name}";
if (!Directory.Exists(loacalFolder))
Directory.CreateDirectory(loacalFolder);
var fs = sftp.ListDirectory(remotePath + "\\" + file.Name);
foreach (var f in fs)
{
if (f.IsDirectory)
{
}
else
{
var byt = sftp.ReadAllBytes(f.FullName);//(remotePath + "\\" + file.Name);
File.WriteAllBytes(loacalFolder + "\\" + f.Name, byt);
}
}
}
else
{
var byt = sftp.ReadAllBytes(file.FullName);//(remotePath + "\\" + file.Name);
File.WriteAllBytes(localPath + "\\" + file.Name, byt);
}
}
catch
{
exeResult.Message = $"Exception to copy {file.Name}";
}
}
Disconnect();
exeResult.Status = true;
//var byt = sftp.ReadAllBytes(remotePath);
Disconnect();
//File.WriteAllBytes(localPath, byt);
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("SFTP文件获取失败,原因:{0}", ex.Message));
Disconnect();
//throw new Exception(string.Format("SFTP文件获取失败,原因:{0}", ex.Message));
exeResult.Message = $"Copy file fail{ex.Message}";
}
return exeResult;
}
#endregion
#region SFTP获取文件
/// <summary> 只能读取二层,待修改
/// SFTP获取文件
/// </summary>
/// <param name="remotePath">远程路径</param>
/// <param name="localPath">本地路径</param>
public ExecutionResult RecursionGetFolder(string remotePath, string localPath)
{
ExecutionResult exeResult = new ExecutionResult();
try
{
Connect();
RecursionCopy(remotePath, localPath);
Disconnect();
exeResult.Message = "get the whole folder successfully!";
exeResult.Status = true;
}
catch (Exception ex)
{
Disconnect();
exeResult.Message = $"Copy file fail{ex.Message}";
}
return exeResult;
}
#endregion
/// <summary>
/// 递归Copy
/// </summary>
/// <param name="remotePath"></param>
/// <param name="localPath"></param>
public void RecursionCopy(string remotePath, string localPath)
{
if (!sftp.Exists(remotePath))
{
return;
}
//
//var strDesNew = System.IO.Path.Combine(localPath, System.IO.Path.GetFileName(remotePath));
var strDesNew = localPath;
if (!Directory.Exists(strDesNew))
{
Directory.CreateDirectory(strDesNew);
}
var files = sftp.ListDirectory(remotePath);
if (files == null)
{
return;
}
foreach (var file in files)
{
if (file.IsDirectory)
{
RecursionCopy(file.FullName, strDesNew);
}
else
{
var byt = sftp.ReadAllBytes(file.FullName);
File.WriteAllBytes(strDesNew + "\\" + file.Name, byt);
}
}
}
public void RecursionUpload(string localPath, string remotePath)
{
if (!File.Exists(localPath))
{
return;
}
//
//var strDesNew = System.IO.Path.Combine(remotePath, System.IO.Path.GetFileName(localPath));
var strDesNew = remotePath;
if (!sftp.Exists(strDesNew))
{
sftp.CreateDirectory(strDesNew);
}
var files = sftp.ListDirectory(localPath);
if (files == null)
{
return;
}
foreach (var file in files)
{
if (file.IsDirectory)
{
RecursionUpload(file.FullName, strDesNew);
}
else
{
var byt = File.ReadAllBytes(file.FullName);
sftp.WriteAllBytes(strDesNew + "\\" + file.Name, byt);
}
}
}
#region 删除SFTP文件
/// <summary>
/// 删除SFTP文件
/// </summary>
/// <param name="remoteFile">远程路径</param>
public void Delete(string remoteFile)
{
try
{
Connect();
sftp.Delete(remoteFile);
Disconnect();
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("SFTP文件删除失败,原因:{0}", ex.Message));
throw new Exception(string.Format("SFTP文件删除失败,原因:{0}", ex.Message));
}
}
#endregion
#region 创建目录
/// <summary>
/// 创建目录
/// </summary>
/// <param name="remotePath">远程目录</param>
public void CreateDirectory(string remotePath)
{
try
{
string[] paths = remotePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string curPath = "/";
for (int i = 0; i < paths.Length; i++)
{
curPath += paths[i];
if (!sftp.Exists(curPath))
{
sftp.CreateDirectory(curPath);
}
if (i < paths.Length - 1)
curPath += "/";
}
}
catch (Exception ex)
{
if (sftp.IsConnected)
Disconnect();
throw new Exception(string.Format("创建目录失败,原因:{0}", ex.Message));
}
}
#endregion
#region 获取SFTP文件列表
/// <summary>
/// 获取SFTP文件列表
/// </summary>
/// <param name="remotePath">远程目录</param>
/// <param name="fileSuffix">文件后缀</param>
/// <returns></returns>
public ArrayList GetFileList(string remotePath, string fileSuffix)
{
try
{
Connect();
var files = sftp.ListDirectory(remotePath);
Disconnect();
var objList = new ArrayList();
foreach (var file in files)
{
string name = file.Name;
if (name.Length > (fileSuffix.Length + 1) && fileSuffix == name.Substring(name.Length - fileSuffix.Length))
{
objList.Add(name);
}
}
return objList;
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("SFTP文件列表获取失败,原因:{0}", ex.Message));
throw new Exception(string.Format("SFTP文件列表获取失败,原因:{0}", ex.Message));
}
}
#endregion
#region 移动SFTP文件
/// <summary>
/// 移动SFTP文件
/// </summary>
/// <param name="oldRemotePath">旧远程路径</param>
/// <param name="newRemotePath">新远程路径</param>
public void Move(string oldRemotePath, string newRemotePath)
{
try
{
Connect();
sftp.RenameFile(oldRemotePath, newRemotePath);
Disconnect();
}
catch (Exception ex)
{
// TxtLog.WriteTxt(CommonMethod.GetProgramName(), string.Format("SFTP文件移动失败,原因:{0}", ex.Message));
throw new Exception(string.Format("SFTP文件移动失败,原因:{0}", ex.Message));
}
}
#endregion
}
}