C# 利用FluentFTP实现FTP上传下载功能

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上传下载的全部内容,旨在抛砖引玉,共同学习,一起进步。

posted @ 2023-02-21 12:58  老码识途呀  阅读(3969)  评论(0编辑  收藏  举报