C#利用FluentFTP實(shí)現(xiàn)FTP上傳下載功能詳解
FTP作為日常工作學(xué)習(xí)中,非常重要的一個(gè)文件傳輸存儲(chǔ)空間,想必大家都非常的熟悉了,那么如何快速的實(shí)現(xiàn)文件的上傳下載功能呢,本文以一個(gè)簡單的小例子,簡述如何通過FluentFTP實(shí)現(xiàn)文件的上傳和下載功能。僅供學(xué)習(xí)分享使用,如有不足之處,還請指正。
FTP基礎(chǔ)知識(shí)
文件傳輸協(xié)議(File Transfer Protocol,F(xiàn)TP)是用于在網(wǎng)絡(luò)上進(jìn)行文件傳輸?shù)囊惶讟?biāo)準(zhǔn)協(xié)議,它工作在 OSI 模型的第七層, TCP 模型的第四層, 即應(yīng)用層, 使用 TCP 傳輸而不是 UDP, 客戶在和服務(wù)器建立連接前要經(jīng)過一個(gè)“三次握手”的過程, 保證客戶與服務(wù)器之間的連接是可靠的, 而且是面向連接, 為數(shù)據(jù)傳輸提供可靠保證。FTP允許用戶以文件操作的方式(如文件的增、刪、改、查、傳送等)與另一主機(jī)相互通信。然而, 用戶并不真正登錄到自己想要存取的計(jì)算機(jī)上面而成為完全用戶, 可用FTP程序訪問遠(yuǎn)程資源, 實(shí)現(xiàn)用戶往返傳輸文件、目錄管理以及訪問電子郵件等等, 即使雙方計(jì)算機(jī)可能配有不同的操作系統(tǒng)和文件存儲(chǔ)方式。
FTP環(huán)境搭建
在windows操作系統(tǒng)中,F(xiàn)TP可以通過(Internet Inforamtion Services, IIS)管理器進(jìn)行創(chuàng)建,創(chuàng)建成功后即可進(jìn)行查看,如下所示:

FluentFTP安裝
FluentFTP是一款基于.Net的FTP和FTPS的客戶端動(dòng)態(tài)庫,操作簡單便捷。

首先創(chuàng)建基于.Net Framework 4.6.1的winform應(yīng)用程序,然后通過Nuget包管理器進(jìn)行安裝,如下所示:

示例演示
主要實(shí)現(xiàn)基于FTP的上傳,下載,瀏覽等功能,如下所示:

進(jìn)入文件夾及右鍵下載,如下所示:

示例源碼
FtpHelper類源碼,封裝了FTP文件的檢索,上傳,下載等功能,如下所示:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FluentFTP;
namespace DemoFtp
{
public class FtpHelper
{
#region 屬性與構(gòu)造函數(shù)
/// <summary>
/// IP地址
/// </summary>
public string IpAddr { get; set; }
/// <summary>
/// 相對(duì)路徑
/// </summary>
public string RelatePath { get; set; }
/// <summary>
/// 端口號(hào)
/// </summary>
public int Port { get; set; }
/// <summary>
/// 用戶名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 密碼
/// </summary>
public string Password { get; set; }
public FtpHelper()
{
}
public FtpHelper(string ipAddr, int port, string userName, string password, string relatePath)
{
this.IpAddr = ipAddr;
this.Port = port;
this.UserName = userName;
this.Password = password;
this.RelatePath = relatePath;
}
#endregion
#region 方法
public FtpListItem[] ListDir() {
FtpListItem[] lists;
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect();
ftpClient.SetWorkingDirectory(this.RelatePath);
lists = ftpClient.GetListing();
}
return lists;
}
public void UpLoad(string dir, string file, out bool isOk)
{
isOk = false;
FileInfo fi = new FileInfo(file);
using (FileStream fs = fi.OpenRead())
{
//long length = fs.Length;
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect();
ftpClient.SetWorkingDirectory(this.RelatePath);
string remotePath = dir + "/" + Path.GetFileName(file);
var ftpRemodeExistsMode = file.EndsWith(".txt") ? FtpRemoteExists.Overwrite : FtpRemoteExists.Skip;
FtpStatus status = ftpClient.UploadStream(fs, remotePath, ftpRemodeExistsMode, true);
isOk = status == FtpStatus.Success;
}
}
}
/// <summary>
/// 上傳多個(gè)文件
/// </summary>
/// <param name="files"></param>
/// <param name="isOk"></param>
public void UpLoad(string dir, string[] files, out bool isOk)
{
isOk = false;
if (CheckDirIsExists(dir))
{
foreach (var file in files)
{
UpLoad(dir, file, out isOk);
}
}
}
private bool CheckDirIsExists(string dir)
{
bool flag = false;
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect();
ftpClient.SetWorkingDirectory(this.RelatePath);
flag = ftpClient.DirectoryExists(dir);
if (!flag)
{
flag = ftpClient.CreateDirectory(dir);
}
}
return flag;
}
/// <summary>
/// 下載ftp
/// </summary>
/// <param name="localAddress"></param>
/// <param name="remoteAddress"></param>
/// <returns></returns>
public bool DownloadFile(string localAddress, string remoteAddress)
{
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.SetWorkingDirectory("/");
ftpClient.Connect();
if (ftpClient.DownloadFile(localAddress, remoteAddress) == FtpStatus.Success)
{
return true;
}
return false;
}
}
#endregion
}
}每一個(gè)FTP文件或文件夾,由一個(gè)自定義用戶控件【PictureBox+Label+ContextMenu】表示,這樣便于處理與顯示:
using DemoFtp.Properties;
using FluentFTP;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DemoFtp
{
public partial class FtpElementControl : UserControl
{
public Action<FtpListItem> SubFolderClick;
public Action<FtpListItem> DownLoadClick;
private FtpListItem ftpListItem;
public FtpElementControl(FtpListItem ftpListItem)
{
InitializeComponent();
this.ftpListItem = ftpListItem;
}
public FtpElementControl()
{
InitializeComponent();
}
public void InitControl()
{
if (ftpListItem.Type == FtpObjectType.Directory)
{
this.pbIcon.Image = Resources.folder.ToBitmap();
}
else if (ftpListItem.Type == FtpObjectType.File)
{
var name = ftpListItem.Name;
var ext = Path.GetExtension(name).ToLower().Substring(1);
if (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "bmp" || ext == "gif")
{
this.pbIcon.Image = Resources.pictures.ToBitmap();
}
else if (ext == "doc" || ext == "docx")
{
this.pbIcon.Image = Resources.doc.ToBitmap();
}
else if (ext == "exe")
{
this.pbIcon.Image = Resources.setup.ToBitmap();
}
else
{
this.pbIcon.Image = Resources.file;
}
}
else
{
this.pbIcon.Image = Resources.file;
}
this.lblName.Text = ftpListItem.Name;
}
private void FtpElementControl_Load(object sender, EventArgs e)
{
}
/// <summary>
/// 子菜單下載功能
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
this.DownLoadClick?.Invoke(ftpListItem);
}
/// <summary>
/// 雙擊打開
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pbIcon_DoubleClick(object sender, EventArgs e)
{
this.SubFolderClick?.Invoke(ftpListItem);
}
}
}主頁面由一系列用戶操作框和按鈕組成,完成對(duì)FTP的基本操作,如下所示:
using FluentFTP;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DemoFtp
{
public partial class MainForm : Form
{
private FtpHelper ftpHelper;
public MainForm()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
var url = txtFtpUrl.Text;
var userName = txtUserName.Text;
var password = txtPassword.Text;
var port = txtPort.Text;
if (this.lblRelatePath.Text != "/")
{
this.lblRelatePath.Text = "/";
}
var relatePath = this.lblRelatePath.Text;
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(port))
{
MessageBox.Show("路徑和賬號(hào)密碼不可為空");
return;
}
if (ftpHelper == null)
{
ftpHelper = new FtpHelper(url, int.Parse(port), userName, password, relatePath);
}
ListDir();
}
public void SubFolder(FtpListItem ftpListItem)
{
if (ftpListItem.Type == FtpObjectType.Directory)
{
var fullName = ftpListItem.FullName;
ftpHelper.RelatePath = fullName;
ListDir();
this.lblRelatePath.Text = fullName;
}
}
private void Download(FtpListItem ftpListItem) {
var fullName=ftpListItem.FullName;
var fileName = Path.GetFileName(fullName);
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = fileName;
sfd.Title = "不載";
sfd.Filter = "所有文檔|*.*";
if (DialogResult.OK == sfd.ShowDialog()) {
ftpHelper.DownloadFile(sfd.FileName, fullName);
}
}
private void ListDir()
{
this.ftpContainer.Controls.Clear();
var ftpListItems = this.ftpHelper.ListDir();
if (ftpListItems != null && ftpListItems.Length > 0)
{
foreach (var ftpListItem in ftpListItems)
{
FtpElementControl ftpControl = new FtpElementControl(ftpListItem);
ftpControl.InitControl();
ftpControl.DownLoadClick += Download;
ftpControl.SubFolderClick += SubFolder;
this.ftpContainer.Controls.Add(ftpControl);
}
}
}
private void btnUpload_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "所有文件|*.*";
ofd.Title = "請選擇需要上傳的文件";
if (DialogResult.OK == ofd.ShowDialog()) {
var localFile=ofd.FileName;
ftpHelper.UpLoad(this.lblRelatePath.Text, localFile, out bool isOk);
if (isOk) {
ListDir();
}
}
}
private void pbReturn_Click(object sender, EventArgs e)
{
var relativePath=this.lblRelatePath.Text;
if (relativePath == "/") {
return;
}
relativePath = relativePath.Substring(0, relativePath.LastIndexOf("/")+1);
ftpHelper.RelatePath=relativePath;
ListDir();
this.lblRelatePath.Text = relativePath;
}
}
}以上就是C#利用FluentFTP實(shí)現(xiàn)FTP上傳下載功能詳解的詳細(xì)內(nèi)容,更多關(guān)于C# FTP上傳下載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# 反射與 Quartz 實(shí)現(xiàn)流程處理詳情
根據(jù)要實(shí)現(xiàn)流程處理,比如用戶可以定義一個(gè)定時(shí)任務(wù),每周一查看報(bào)表。任務(wù)是用Quartz可實(shí)現(xiàn),但用戶自己選擇報(bào)表就比較麻煩,這時(shí)因?yàn)橄到y(tǒng)的不同模塊的生成報(bào)表的函數(shù)不同,這時(shí)便可以傳入一個(gè)方法名和方法的輸入?yún)?shù),就可以調(diào)用該方法。下面小編我為大家介紹具體過程2021-09-09
如何利用C#正則表達(dá)式判斷是否是有效的文件及文件夾路徑
項(xiàng)目中少不了讀取或設(shè)置文件路徑的功能,如何才能對(duì)輸入的路徑是否合法進(jìn)行判斷呢?下面這篇文章主要給大家介紹了關(guān)于C#利用正則表達(dá)式判斷是否是有效的文件及文件夾路徑的相關(guān)資料,需要的朋友可以參考下2022-04-04
C#中的矩形數(shù)組(多維數(shù)組)和鋸齒數(shù)組的實(shí)現(xiàn)
本文主要介紹了C#中的矩形數(shù)組(多維數(shù)組)和鋸齒數(shù)組的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
C#設(shè)計(jì)模式之ChainOfResponsibility職責(zé)鏈模式解決真假美猴王問題實(shí)例
這篇文章主要介紹了C#設(shè)計(jì)模式之ChainOfResponsibility職責(zé)鏈模式解決真假美猴王問題,簡單說明了責(zé)任鏈模式的概念,并結(jié)合《西游記》中真假美猴王故事背景為實(shí)例分析了責(zé)任鏈模式的具體使用技巧,需要的朋友可以參考下2017-09-09
C# 獲取打印機(jī)當(dāng)前狀態(tài)的方法
C# 獲取打印機(jī)當(dāng)前狀態(tài)的方法,需要的朋友可以參考一下2013-04-04
C# 批量生成隨機(jī)密碼必須包含數(shù)字和字母并用加密算法加密
這篇文章主要介紹了C# 批量生成隨機(jī)密碼必須包含數(shù)字和字母并用加密算法加密,需要的朋友參考下2017-01-01

