C# FTPHelper實現FTP伺服器文件讀寫操作,支持SSL協議(FTP伺服器為:Serv-U10.0)。 SSL測試調用代碼 任何地方如有紕漏,歡迎諸位道友指教。 ...
C# FTPHelper實現FTP伺服器文件讀寫操作,支持SSL協議(FTP伺服器為:Serv-U10.0)。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; namespace FTPTest { public class FTPHelper { #region 變數 /// <summary> /// FTP請求對象 /// </summary> FtpWebRequest request = null; /// <summary> /// FTP響應對象 /// </summary> FtpWebResponse response = null; /// <summary> /// FTP伺服器長地址 /// </summary> public string FtpURI { get; private set; } /// <summary> /// FTP伺服器IP /// </summary> public string ServerIP { get; private set; } /// <summary> /// FTP埠 /// </summary> public int ServerPort { get; private set; } /// <summary> /// FTP用戶 /// </summary> public string Username { get; private set; } /// <summary> /// FTP密碼 /// </summary> public string Password { get; private set; } /// <summary> /// 是否啟用SSL /// </summary> public bool EnableSsl { get; private set; } #endregion #region 構造 /// <summary> /// 初始化 /// </summary> /// <param name="FtpServerIP">IP</param> /// <param name="ftpServerPort">埠</param> /// <param name="FtpUserID">用戶名</param> /// <param name="FtpPassword">密碼</param> public FTPHelper(string ftpServerIP, int ftpServerPort, string ftpUsername, string ftpPassword, bool ftpEnableSsl = false) { ServerIP = ftpServerIP; ServerPort = ftpServerPort; Username = ftpUsername; Password = ftpPassword; EnableSsl = ftpEnableSsl; FtpURI = string.Format("ftp://{0}:{1}/", ftpServerIP, ftpServerPort); } ~FTPHelper() { if (response != null) { response.Close(); response = null; } if (request != null) { request.Abort(); request = null; } } #endregion #region 方法 /// <summary> /// 建立FTP鏈接,返迴響應對象 /// </summary> /// <param name="uri">FTP地址</param> /// <param name="ftpMethod">操作命令</param> private FtpWebResponse Open(Uri uri, string ftpMethod) { try { request = (FtpWebRequest)FtpWebRequest.Create(uri); request.Method = ftpMethod; request.UseBinary = true; request.KeepAlive = false; request.UsePassive = true;//被動模式 request.EnableSsl = EnableSsl; request.Credentials = new NetworkCredential(Username, Password); request.Timeout = 30000; //首次連接FTP Server時,會有一個證書分配過程。 //根據驗證過程,遠程證書無效。 ServicePoint sp = request.ServicePoint; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate); return (FtpWebResponse)request.GetResponse(); } catch (Exception ex) { return null; } } /// <summary> /// 建立FTP鏈接,返回請求對象 /// </summary> /// <param name="uri">FTP地址</param> /// <param name="ftpMethod">操作命令</param> private FtpWebRequest OpenRequest(Uri uri, string ftpMethod) { try { request = (FtpWebRequest)WebRequest.Create(uri); request.Method = ftpMethod; request.UseBinary = true; request.KeepAlive = false; request.UsePassive = true;//被動模式 request.EnableSsl = EnableSsl; request.Credentials = new NetworkCredential(Username, Password); request.Timeout = 30000; ServicePoint sp = request.ServicePoint; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate); return request; } catch (Exception ex) { return null; } } /// <summary> /// 證書驗證回調 /// </summary> private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } /// <summary> /// 下載文件 /// </summary> /// <param name="remoteFileName">遠程文件</param> /// <param name="localFileName">本地文件</param> public bool Get(string remoteFileName, string localFileName) { response = Open(new Uri(FtpURI + remoteFileName), WebRequestMethods.Ftp.DownloadFile); if (response == null) return false; try { using (FileStream outputStream = new FileStream(localFileName, FileMode.Create)) { using (Stream ftpStream = response.GetResponseStream()) { long length = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } } } return true; } catch { return false; } } /// <summary> /// 文件上傳 /// </summary> /// <param name="localFileName">本地文件</param> /// <param name="localFileName">遠程文件</param> public bool Put(string localFileName, string remoteFileName) { FileInfo fi = new FileInfo(localFileName); if (fi.Exists == false) return false; request = OpenRequest(new Uri(FtpURI + remoteFileName), WebRequestMethods.Ftp.UploadFile); if (request == null) return false; request.ContentLength = fi.Length; int buffLength = 2048; byte[] buff = new byte[buffLength]; int contentLen; try { using (var fs = fi.OpenRead()) { using (var strm = request.GetRequestStream()) { contentLen = fs.Read(buff, 0, buffLength); while (contentLen != 0) { strm.Write(buff, 0, contentLen); contentLen = fs.Read(buff, 0, buffLength); } } } return true; } catch { return false; } } /// <summary> /// 刪除文件 /// </summary> public bool DeleteFile(string fileName) { response = Open(new Uri(FtpURI + fileName), WebRequestMethods.Ftp.DeleteFile); return response == null ? false : true; } /// <summary> /// 創建目錄 /// </summary> public bool CreateDirectory(string dirName) { response = Open(new Uri(FtpURI + dirName), WebRequestMethods.Ftp.MakeDirectory); return response == null ? false : true; } /// <summary> /// 刪除目錄(包括下麵所有子目錄和子文件) /// </summary> public bool DeleteDirectory(string dirName) { var listAll = GetDirectoryAndFiles(dirName); if (listAll == null) return false; foreach (var m in listAll) { if (m.IsDirectory) DeleteDirectory(m.Path); else DeleteFile(m.Path); } response = Open(new Uri(FtpURI + dirName), WebRequestMethods.Ftp.RemoveDirectory); return response == null ? false : true; } /// <summary> /// 獲取目錄的文件和一級子目錄信息 /// </summary> public List<FileStruct> GetDirectoryAndFiles(string dirName) { var fileList = new List<FileStruct>(); response = Open(new Uri(FtpURI + dirName), WebRequestMethods.Ftp.ListDirectoryDetails); if (response == null) return fileList; try { using (var stream = response.GetResponseStream()) { using (var sr = new StreamReader(stream, Encoding.Default)) { string line = null; while ((line = sr.ReadLine()) != null) { //line的格式如下:serv-u(文件夾為第1位為d) //drw-rw-rw- 1 user group 0 Jun 10 2019 BStatus //-rw-rw-rw- 1 user group 625 Dec 7 2018 FTP文檔.txt string[] arr = line.Split(' '); if (arr.Length < 12) continue;//remotePath不為空時,第1行返回值為:total 10715 var model = new FileStruct() { IsDirectory = line.Substring(0, 3) == "drw" ? true : false, Name = arr[arr.Length - 1], Path = dirName + "/" + arr[arr.Length - 1] }; if (model.Name != "." && model.Name != "..")//排除.和.. { fileList.Add(model); } } } } return fileList; } catch { return fileList; } } /// <summary> /// 獲取目錄的文件 /// </summary> public List<FileStruct> GetFiles(string dirName) { var fileList = new List<FileStruct>(); response = Open(new Uri(FtpURI + dirName), WebRequestMethods.Ftp.ListDirectory); if (response == null) return fileList; try { using (var stream = response.GetResponseStream()) { using (var sr = new StreamReader(stream, Encoding.Default)) { string line = null; while ((line = sr.ReadLine()) != null) { var model = new FileStruct() { Name = line, Path = dirName + "/" + line }; fileList.Add(model); } } } return fileList; } catch { return fileList; } } /// <summary> /// 獲得遠程文件大小 /// </summary> public long GetFileSize(string fileName) { response = Open(new Uri(FtpURI + fileName), WebRequestMethods.Ftp.GetFileSize); return response == null ? -1 : response.ContentLength; } /// <summary> /// 文件是否存在 /// </summary> public bool FileExist(string fileName) { long length = GetFileSize(fileName); return length == -1 ? false : true; } /// <summary> /// 目錄是否存在 /// </summary> public bool DirectoryExist(string dirName) { var list = GetDirectoryAndFiles(Path.GetDirectoryName(dirName)); return list.Count(m => m.IsDirectory == true && m.Name == dirName) > 0 ? true : false; } /// <summary> /// 更改目錄或文件名 /// </summary> /// <param name="oldName">老名稱</param> /// <param name="newName">新名稱</param> public bool ReName(string oldName, string newName) { request = OpenRequest(new Uri(FtpURI + oldName), WebRequestMethods.Ftp.Rename); request.RenameTo = newName; try { response = (FtpWebResponse)request.GetResponse(); return response == null ? false : true; } catch { return false; } } #endregion } /// <summary> /// FTP文件類 /// </summary> public class FileStruct { /// <summary> /// 是否為目錄 /// </summary> public bool IsDirectory { get; set; } /// <summary> /// 創建時間(FTP上無法獲得時間) /// </summary> //public DateTime CreateTime { get; set; } /// <summary> /// 文件或目錄名稱 /// </summary> public string Name { get; set; } /// <summary> /// 路徑 /// </summary> public string Path { get; set; } } }
SSL測試調用代碼
var ftp = new FTPHelper("192.168.0.36", 21, "test", "1", true); var list = ftp.GetFiles("");
任何地方如有紕漏,歡迎諸位道友指教。