C# 利用FluentFTP實現FTP上傳下載功能

来源:https://www.cnblogs.com/hsiang/archive/2023/02/21/17139285.html
-Advertisement-
Play Games

FTP作為日常工作學習中,非常重要的一個文件傳輸存儲空間,想必大家都非常的熟悉了,那麼如何快速的實現文件的上傳下載功能呢,本文以一個簡單的小例子,簡述如何通過FluentFTP實現文件的上傳和下載功能。僅供學習分享使用,如有不足之處,還請指正。 ...


FTP作為日常工作學習中,非常重要的一個文件傳輸存儲空間,想必大家都非常的熟悉了,那麼如何快速的實現文件的上傳下載功能呢,本文以一個簡單的小例子,簡述如何通過FluentFTP實現文件的上傳和下載功能。僅供學習分享使用,如有不足之處,還請指正。

FTP基礎知識

文件傳輸協議(File Transfer Protocol,FTP)是用於在網路上進行文件傳輸的一套標準協議,它工作在 OSI 模型的第七層, TCP 模型的第四層, 即應用層, 使用 TCP 傳輸而不是 UDP, 客戶在和伺服器建立連接前要經過一個“三次握手”的過程, 保證客戶與伺服器之間的連接是可靠的, 而且是面向連接, 為數據傳輸提供可靠保證。FTP允許用戶以文件操作的方式(如文件的增、刪、改、查、傳送等)與另一主機相互通信。然而, 用戶並不真正登錄到自己想要存取的電腦上面而成為完全用戶, 可用FTP程式訪問遠程資源, 實現用戶往返傳輸文件、目錄管理以及訪問電子郵件等等, 即使雙方電腦可能配有不同的操作系統和文件存儲方式。

FTP環境搭建

在windows操作系統中,FTP可以通過(Internet Inforamtion Services, IIS)管理器進行創建,創建成功後即可進行查看,如下所示:

 

FluentFTP安裝

FluentFTP是一款基於.Net的FTP和FTPS的客戶端動態庫,操作簡單便捷。

 

 

首先創建基於.Net Framework 4.6.1的winform應用程式,然後通過Nuget包管理器進行安裝,如下所示:

 

示例演示

 主要實現基於FTP的上傳,下載,瀏覽等功能,如下所示:

 

 進入文件夾及右鍵下載,如下所示:

 

示例源碼

FtpHelper類源碼,封裝了FTP文件的檢索,上傳,下載等功能,如下所示:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Net;
  6 using System.Text;
  7 using System.Threading;
  8 using System.Threading.Tasks;
  9 using FluentFTP;
 10 
 11 namespace DemoFtp
 12 {
 13     public class FtpHelper
 14     {
 15         #region 屬性與構造函數
 16 
 17         /// <summary>
 18         /// IP地址
 19         /// </summary>
 20         public string IpAddr { get; set; }
 21 
 22         /// <summary>
 23         /// 相對路徑
 24         /// </summary>
 25         public string RelatePath { get; set; }
 26 
 27         /// <summary>
 28         /// 埠號
 29         /// </summary>
 30         public int Port { get; set; }
 31 
 32         /// <summary>
 33         /// 用戶名
 34         /// </summary>
 35         public string UserName { get; set; }
 36 
 37         /// <summary>
 38         /// 密碼
 39         /// </summary>
 40         public string Password { get; set; }
 41 
 42         public FtpHelper()
 43         {
 44 
 45         }
 46 
 47         public FtpHelper(string ipAddr, int port, string userName, string password, string relatePath)
 48         {
 49             this.IpAddr = ipAddr;
 50             this.Port = port;
 51             this.UserName = userName;
 52             this.Password = password;
 53             this.RelatePath = relatePath;
 54         }
 55 
 56         #endregion
 57 
 58         #region 方法
 59 
 60         public FtpListItem[] ListDir() {
 61             FtpListItem[] lists;
 62             using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
 63             {
 64                 ftpClient.Connect();
 65                 ftpClient.SetWorkingDirectory(this.RelatePath);
 66                 lists = ftpClient.GetListing();
 67             }
 68             return lists;
 69         }
 70 
 71         public void UpLoad(string dir, string file, out bool isOk)
 72         {
 73             isOk = false;
 74             FileInfo fi = new FileInfo(file);
 75             using (FileStream fs = fi.OpenRead())
 76             {
 77                 //long length = fs.Length;
 78                 using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
 79                 {
 80                     ftpClient.Connect();
 81                     ftpClient.SetWorkingDirectory(this.RelatePath);
 82                     string remotePath = dir + "/" + Path.GetFileName(file);
 83                     var ftpRemodeExistsMode = file.EndsWith(".txt") ? FtpRemoteExists.Overwrite : FtpRemoteExists.Skip;
 84                     FtpStatus status = ftpClient.UploadStream(fs, remotePath, ftpRemodeExistsMode, true);
 85                     isOk = status == FtpStatus.Success;
 86 
 87                 }
 88             }
 89          
 90         }
 91 
 92         /// <summary>
 93         /// 上傳多個文件
 94         /// </summary>
 95         /// <param name="files"></param>
 96         /// <param name="isOk"></param>
 97         public void UpLoad(string dir, string[] files, out bool isOk)
 98         {
 99             isOk = false;
100             if (CheckDirIsExists(dir))
101             {
102                 foreach (var file in files)
103                 {
104                     UpLoad(dir, file, out isOk);
105                 }
106             }
107         }
108 
109 
110         private bool CheckDirIsExists(string dir)
111         {
112             bool flag = false;
113             using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
114             {
115                 ftpClient.Connect();
116                 ftpClient.SetWorkingDirectory(this.RelatePath);
117                 flag = ftpClient.DirectoryExists(dir);
118                 if (!flag)
119                 {
120                     flag = ftpClient.CreateDirectory(dir);
121                 }
122             }
123             return flag;
124 
125 
126         }
127 
128         /// <summary> 
129         /// 下載ftp 
130         /// </summary> 
131         /// <param name="localAddress"></param> 
132         /// <param name="remoteAddress"></param> 
133         /// <returns></returns> 
134         public bool DownloadFile(string localAddress, string remoteAddress)
135         {
136             using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
137             {
138                 ftpClient.SetWorkingDirectory("/");
139                 ftpClient.Connect();
140                 if (ftpClient.DownloadFile(localAddress, remoteAddress) == FtpStatus.Success)
141                 {
142                     return true;
143                 }
144                 return false;
145             }
146         }
147 
148         #endregion
149     }
150 }

每一個FTP文件或文件夾,由一個自定義用戶控制項【PictureBox+Label+ContextMenu】表示,這樣便於處理與顯示:

 1 using DemoFtp.Properties;
 2 using FluentFTP;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.ComponentModel;
 6 using System.Data;
 7 using System.Drawing;
 8 using System.IO;
 9 using System.Linq;
10 using System.Text;
11 using System.Threading.Tasks;
12 using System.Windows.Forms;
13 
14 namespace DemoFtp
15 {
16     public partial class FtpElementControl : UserControl
17     {
18         public Action<FtpListItem> SubFolderClick;
19 
20         public Action<FtpListItem> DownLoadClick;
21 
22         private FtpListItem ftpListItem;
23 
24         public FtpElementControl(FtpListItem ftpListItem)
25         {
26             InitializeComponent();
27             this.ftpListItem = ftpListItem;
28         }
29 
30         public FtpElementControl()
31         {
32             InitializeComponent();
33         }
34 
35         public void InitControl()
36         {
37             if (ftpListItem.Type == FtpObjectType.Directory)
38             {
39                 this.pbIcon.Image = Resources.folder.ToBitmap();
40             }
41             else if (ftpListItem.Type == FtpObjectType.File)
42             {
43                 var name = ftpListItem.Name;
44                 var ext = Path.GetExtension(name).ToLower().Substring(1);
45                 if (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "bmp" || ext == "gif")
46                 {
47                     this.pbIcon.Image = Resources.pictures.ToBitmap();
48                 }
49                 else if (ext == "doc" || ext == "docx")
50                 {
51                     this.pbIcon.Image = Resources.doc.ToBitmap();
52                 }
53                 else if (ext == "exe")
54                 {
55                     this.pbIcon.Image = Resources.setup.ToBitmap();
56                 }
57                 else
58                 {
59                     this.pbIcon.Image = Resources.file;
60                 }
61             }
62             else
63             {
64                 this.pbIcon.Image = Resources.file;
65             }
66             this.lblName.Text = ftpListItem.Name;
67         }
68 
69         private void FtpElementControl_Load(object sender, EventArgs e)
70         {
71             
72         }
73 
74         /// <summary>
75         /// 子菜單下載功能
76         /// </summary>
77         /// <param name="sender"></param>
78         /// <param name="e"></param>
79         private void menu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
80         {
81             this.DownLoadClick?.Invoke(ftpListItem);
82         }
83 
84         /// <summary>
85         /// 雙擊打開
86         /// </summary>
87         /// <param name="sender"></param>
88         /// <param name="e"></param>
89         private void pbIcon_DoubleClick(object sender, EventArgs e)
90         {
91             this.SubFolderClick?.Invoke(ftpListItem);
92         }
93     }
94 }

主頁面由一系列用戶操作框和按鈕組成,完成對FTP的基本操作,如下所示:

  1 using FluentFTP;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.ComponentModel;
  5 using System.Data;
  6 using System.Drawing;
  7 using System.IO;
  8 using System.Linq;
  9 using System.Text;
 10 using System.Threading.Tasks;
 11 using System.Windows.Forms;
 12 
 13 namespace DemoFtp
 14 {
 15     public partial class MainForm : Form
 16     {
 17         private FtpHelper ftpHelper;
 18 
 19         public MainForm()
 20         {
 21             InitializeComponent();
 22         }
 23 
 24         private void btnLogin_Click(object sender, EventArgs e)
 25         {
 26             var url = txtFtpUrl.Text;
 27             var userName = txtUserName.Text;
 28             var password = txtPassword.Text;
 29             var port = txtPort.Text;
 30             if (this.lblRelatePath.Text != "/")
 31             {
 32                 this.lblRelatePath.Text = "/";
 33             }
 34             var relatePath = this.lblRelatePath.Text;
 35             if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(port))
 36             {
 37                 MessageBox.Show("路徑和賬號密碼不可為空");
 38                 return;
 39             }
 40             if (ftpHelper == null)
 41             {
 42                 ftpHelper = new FtpHelper(url, int.Parse(port), userName, password, relatePath);
 43 
 44             }
 45             ListDir();
 46         }
 47 
 48         public void SubFolder(FtpListItem ftpListItem)
 49         {
 50             if (ftpListItem.Type == FtpObjectType.Directory)
 51             {
 52                 var fullName = ftpListItem.FullName;
 53                 ftpHelper.RelatePath = fullName;
 54                 ListDir();
 55                 this.lblRelatePath.Text = fullName;
 56             }
 57         }
 58 
 59 
 60         private void Download(FtpListItem ftpListItem) { 
 61             var fullName=ftpListItem.FullName;
 62             var fileName = Path.GetFileName(fullName);
 63             SaveFileDialog sfd = new SaveFileDialog();
 64             sfd.FileName = fileName;
 65             sfd.Title = "不載";
 66             sfd.Filter = "所有文檔|*.*";
 67             if (DialogResult.OK == sfd.ShowDialog()) { 
 68                 ftpHelper.DownloadFile(sfd.FileName, fullName);
 69             }
 70         }
 71 
 72         private void ListDir()
 73         {
 74             this.ftpContainer.Controls.Clear();
 75             var ftpListItems = this.ftpHelper.ListDir();
 76             if (ftpListItems != null && ftpListItems.Length > 0)
 77             {
 78                 foreach (var ftpListItem in ftpListItems)
 79                 {
 80                     FtpElementControl ftpControl = new FtpElementControl(ftpListItem);
 81                     ftpControl.InitControl();
 82                     ftpControl.DownLoadClick += Download;
 83                     ftpControl.SubFolderClick += SubFolder;
 84                     this.ftpContainer.Controls.Add(ftpControl);
 85                 }
 86             }
 87         }
 88 
 89         private void btnUpload_Click(object sender, EventArgs e)
 90         {
 91             OpenFileDialog ofd = new OpenFileDialog();
 92             ofd.Filter = "所有文件|*.*";
 93             ofd.Title = "請選擇需要上傳的文件";
 94             if (DialogResult.OK == ofd.ShowDialog()) { 
 95                 var localFile=ofd.FileName;
 96                 ftpHelper.UpLoad(this.lblRelatePath.Text, localFile, out bool isOk);
 97                 if (isOk) {
 98                     ListDir();
 99                 }
100             }
101         }
102 
103         private void pbReturn_Click(object sender, EventArgs e)
104         {
105             var relativePath=this.lblRelatePath.Text;
106             if (relativePath == "/") {
107                 return;
108             }
109             relativePath = relativePath.Substring(0, relativePath.LastIndexOf("/")+1);
110             ftpHelper.RelatePath=relativePath;
111             ListDir();
112             this.lblRelatePath.Text = relativePath;
113         }
114     }
115 }

以上就是基於FluentFTP實現FTP上傳下載的全部內容,旨在拋磚引玉,共同學習,一起進步。


作者:小六公子
出處:http://www.cnblogs.com/hsiang/
本文版權歸作者和博客園共有,寫文不易,支持原創,歡迎轉載【點贊】,轉載請保留此段聲明,且在文章頁面明顯位置給出原文連接,謝謝。
關註個人公眾號,定時同步更新技術及職場文章


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近OpenAI的ChatGPT真的是到處都在刷屏,我想你已經看過很多關於ChatGPT的文章或者視頻了,我就不過多介紹了。 不過你碰巧還不知道的話,可以先百度一下,然後再回來繼續。 與ChatGPT對話很有趣,甚至很有啟發性。有人用它聊天,有人用它寫代碼,太多省時省力的工作,都可以由它完成,我們的 ...
  • MD_CHANGE_MRP_DATA:在我看來,它是MRP上最重要的BAdI。它允許您在物料需求計劃或 MD04 交易記錄期間更改任何物料需求計劃元素。最常見的用途是使物料需求計劃元素與物料需求計劃無關,但它也可用於其他更改,例如數量更改。您可以在文檔“使用 BAdI MD_CHANGE_MRP_D ...
  • 這篇文章主要描述分散式通信中的發佈訂閱模式,這是一種非同步通信模式,它可以解耦消息的生產者和消費者,提高系統的穩定性。同時,文章也描述了Kafka的架構以及主題、分區和消費組。 ...
  • 輸入輸出 print()函數 sep=' ' 數據之間一空格分割,預設是空格 end='\n' 在列印後會額外的加一個數據,預設是換行符 print("hello", "world") print("hello", "world", sep=' ') """ 上面兩行代碼輸出語句分別為: hello ...
  • cron 有2種表達形式 6個時間刻度的話 * * * * * * 分別對應 秒 分 時 日 月 星期 ; 7個時間刻度的話 * * * * * * * 分別對應 秒 分 時 日 月 星期 年; >>>註意 時間刻度之間得用 ‘空格’分隔 對應的通配符有: * ? / - , 星號(*): 指的是 ...
  • 阿裡雲物聯網平臺專用工具基本涵蓋了阿裡雲物聯網平臺提供你主要管理功能,可以方便創建產品、設備、物模型,查看設備實時屬性,事件,發送服務和查看服務日誌等等 ...
  • 近期,業務調整,需要內網讀取數據後存入到外網,同時,其他伺服器也需要讀取數據,於是我又盯上了RabbitMQ。在展開業務代碼前,先看下RabbitMQ整體架構,可以看到Exchange和隊列是多對多關係。 下麵,我們詳細說說RabbitMQ的隊列模式:簡單隊列、工作隊列、發佈訂閱模式、路由模式、主題 ...
  • Net 內置記憶體緩存 asp.net 中是有緩存的實現:HttpContext.Cache,緩存的數據是放到 Web 伺服器的進程 記憶體里。 在控制台、WinForm、子線程、SignalR 等不支持 HttpContext 的地方還可以使用 MemoryCache.Default(System.R ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...