C# 通过SshNet上传下载文件

发布时间 2023-12-22 09:30:45作者: CV攻城员

会把本地文件夹压缩成 .tar.gz 文件 后上传

using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using Renci.SshNet;
using System;
using System.IO;
using System.Windows.Forms;

namespace Pack
{
    public delegate void AddTextLog(string log);

    public class SShHelp
    {
        public string ip { get; set; }
        public int port { get; set; }
        public string userName { get; set; }
        public string password { get; set; }
        public AddTextLog addTextLog { get; set; }

        public SShHelp()
        {
           
        }

        public SShHelp(string ip, int port,string userName,string password, AddTextLog _addTextLog)
        {
            this.ip = ip;
            this.port = port;
            this.userName = userName;
            this.password = password;
            _instance = this;
            _instance.addTextLog = _addTextLog;
        }

        private static SShHelp _instance = null;

        public static SShHelp Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new SShHelp();
                }
                return _instance;
            }
        }

        public void ExecuteCommand(string commandText)
        {
            SshClient ssh = new SshClient(ip, port, userName, password);
            ssh.Connect();
            SshCommand cmd = ssh.CreateCommand(commandText);
            cmd.Execute();
            AddLog($"[{userName}]# " + commandText);
            AddLog(cmd.Result);
            if (cmd.Error.Length > 0) AddLog("警告" + cmd.Error);
            ssh.Dispose();
        }

        public void AddLog(string text)
        {
            text = text.Replace("\n", "\r\n");
            if (text.IndexOf("\r\n") == -1)
            {
                text += "\r\n";
            }
            addTextLog(text);
        }


        public string Upload(string workingdirectory, string uploadfile)
        {
            var path = uploadfile.Split('\\');
            string directoryPath = "";
            string strSourceFolderName = "";

            if ((uploadfile.IndexOf(".tar.gz") == -1 && uploadfile.IndexOf(".") > -1 && uploadfile.IndexOf(".db") == -1) || Directory.Exists(uploadfile))
            {
                if (strSourceFolderName.Length == 0)
                    strSourceFolderName = path[path.Length - 1];
                directoryPath = uploadfile.Substring(0, uploadfile.Length - strSourceFolderName.Length);
                if (!CreatTarGzArchive(uploadfile.Substring(0, uploadfile.Length - strSourceFolderName.Length), strSourceFolderName))
                {
                    MessageBox.Show($"上传{uploadfile}失败", "提示:");
                    return string.Empty;
                }
                strSourceFolderName += ".tar.gz";
            }
            using (var client = new SftpClient(ip, port, userName, password)) //创建连接对象
            {
                client.Connect(); //连接
                client.ChangeDirectory(workingdirectory); //切换目录
                var listDirectory = client.ListDirectory(workingdirectory); //获取目录下所有文件
                foreach (var fi in listDirectory) //遍历文件
                {
                    // Console.WriteLine(" - " + fi.Name);
                    // client.DeleteFile(fi.FullName);//删除文件
                }
                string newPath = uploadfile;
                if (!string.IsNullOrEmpty(directoryPath))
                {
                    if (directoryPath.Substring(directoryPath.Length - 2).IndexOf("\\") > -1)
                    {
                        newPath = directoryPath + strSourceFolderName;
                    }
                    else
                    {
                        newPath = directoryPath + "\\" + strSourceFolderName;
                    }
                }

                using (var fileStream = new FileStream(newPath, FileMode.Open))
                {
                    client.BufferSize = 4 * 1024;
                    client.UploadFile(fileStream, Path.GetFileName(newPath));
                    AddLog("上传:" + workingdirectory + "->" + uploadfile);
                }
            }
            if(strSourceFolderName.Length == 0)
            {
                strSourceFolderName = path[path.Length - 1];
            }
            return strSourceFolderName;
        }

        /// <summary>  
        /// 生成  文件  
        /// </summary>  
        /// <param name="strBasePath">文件基目录(源文件、生成文件所在目录)</param>  
        /// <param name="strSourceFolderName">待压缩的源文件夹名</param>  
        public bool CreatTarGzArchive(string strBasePath, string strSourceFolderName)
        {
            if (string.IsNullOrEmpty(strBasePath)
                || string.IsNullOrEmpty(strSourceFolderName)
                || !System.IO.Directory.Exists(strBasePath)
                || !System.IO.Directory.Exists(Path.Combine(strBasePath, strSourceFolderName)))
            {
                return false;
            }

            Environment.CurrentDirectory = strBasePath;
            string strSourceFolderAllPath = Path.Combine(strBasePath, strSourceFolderName);
            string strOupFileAllPath = Path.Combine(strBasePath, strSourceFolderName + ".tar.gz");

            Stream outTmpStream = new FileStream(strOupFileAllPath, FileMode.OpenOrCreate);

            //注意此处源文件大小大于4096KB  
            Stream outStream = new GZipOutputStream(outTmpStream);
            TarArchive archive = TarArchive.CreateOutputTarArchive(outStream, TarBuffer.DefaultBlockFactor);
            TarEntry entry = TarEntry.CreateEntryFromFile(strSourceFolderAllPath);
            archive.WriteEntry(entry, true);

            if (archive != null)
            {
                archive.Close();
            }
            outTmpStream.Close();
            outStream.Close();
            return true;
        }


        /// <summary>
        /// SFTP获取文件
        /// </summary>
        /// <param name="remotePath">远程路径</param>
        /// <param name="localPath">本地路径</param>
        public void DownloadFiles(string remotePath, string localPath)
        {
            using (var client = new SftpClient(ip, port, userName, password)) //创建连接对象
            {
                client.Connect(); 
                var byt = client.ReadAllBytes(remotePath);
                File.WriteAllBytes(localPath, byt);
            }
        }

    }
}