C# 实现FTP客户端


本文是利用C# 实现FTP客户端的小例子,主要实现上传,下载,删除等功能,以供学习分享使用。

思路:

  1. 通过读取FTP站点的目录信息,列出对应的文件及文件夹。
  2. 双击目录,则显示子目录,如果是文件,则点击右键,进行下载和删除操作。
  3. 通过读取本地电脑的目录,以树状结构展示,选择本地文件,右键进行上传操作。

涉及知识点:

  1. FtpWebRequest【实现文件传输协议 (FTP) 客户端】 / FtpWebResponse【封装文件传输协议 (FTP) 服务器对请求的响应】Ftp的操作主要集中在两个类中。
  2. FlowLayoutPanel  【流布局面板】表示一个沿水平或垂直方向动态排放其内容的面板。
  3. ContextMenuStrip 【快捷菜单】 主要用于右键菜单。
  4. 资源文件:Resources 用于存放图片及其他资源。

效果图如下

左边:双击文件夹进入子目录,点击工具栏按钮‘上级目录’返回。文件点击右键进行操作。

右边:文件夹则点击前面+号展开。文件则点击右键进行上传。

核心代码如下

  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 
 10 namespace FtpClient
 11 {
 12     public class FtpHelper
 13     {
 14         #region 属性与构造函数
 15 
 16         /// 
 17         /// IP地址
 18         /// 
 19         public string IpAddr { get; set; }
 20 
 21         /// 
 22         /// 相对路径
 23         /// 
 24         public string RelatePath { get; set; }
 25 
 26         /// 
 27         /// 端口号
 28         /// 
 29         public string Port { get; set; }
 30 
 31         /// 
 32         /// 用户名
 33         /// 
 34         public string UserName { get; set; }
 35 
 36         /// 
 37         /// 密码
 38         /// 
 39         public string Password { get; set; }
 40 
 41        
 42 
 43         public FtpHelper() {
 44 
 45         }
 46 
 47         public FtpHelper(string ipAddr, string port, string userName, string password) {
 48             this.IpAddr = ipAddr;
 49             this.Port = port;
 50             this.UserName = userName;
 51             this.Password = password;
 52         }
 53 
 54         #endregion
 55 
 56         #region 方法
 57 
 58 
 59         /// 
 60         /// 下载文件
 61         /// 
 62         /// 
 63         /// 
 64         public void DownLoad(string filePath, out bool isOk) {
 65             string method = WebRequestMethods.Ftp.DownloadFile;
 66             var statusCode = FtpStatusCode.DataAlreadyOpen;
 67             FtpWebResponse response = callFtp(method);
 68             ReadByBytes(filePath, response, statusCode, out isOk);
 69         }
 70 
 71         public void UpLoad(string file,out bool isOk)
 72         {
 73             isOk = false;
 74             FileInfo fi = new FileInfo(file);
 75             FileStream fs = fi.OpenRead();
 76             long length = fs.Length;
 77             string uri = string.Format("ftp://{0}:{1}{2}", this.IpAddr, this.Port, this.RelatePath);
 78             FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
 79             request.Credentials = new NetworkCredential(UserName, Password);
 80             request.Method = WebRequestMethods.Ftp.UploadFile;
 81             request.UseBinary = true;
 82             request.ContentLength = length;
 83             request.Timeout = 10 * 1000;
 84             try
 85             {
 86                 Stream stream = request.GetRequestStream();
 87 
 88                 int BufferLength = 2048; //2K   
 89                 byte[] b = new byte[BufferLength];
 90                 int i;
 91                 while ((i = fs.Read(b, 0, BufferLength)) > 0)
 92                 {
 93                     stream.Write(b, 0, i);
 94                 }
 95                 stream.Close();
 96                 stream.Dispose();
 97                 isOk = true;
 98             }
 99             catch (Exception ex)
100             {
101                 Console.WriteLine(ex.ToString());
102             }
103             finally {
104                 if (request != null)
105                 {
106                     request.Abort();
107                     request = null;
108                 }
109             }
110         }
111 
112         /// 
113         /// 删除文件
114         /// 
115         /// 
116         /// 
117         public string[] DeleteFile(out bool isOk) {
118             string method = WebRequestMethods.Ftp.DeleteFile;
119             var statusCode = FtpStatusCode.FileActionOK;
120             FtpWebResponse response = callFtp(method);
121             return ReadByLine(response, statusCode, out isOk);
122         }
123 
124         /// 
125         /// 展示目录
126         /// 
127         public string[] ListDirectory(out bool isOk)
128         {
129             string method = WebRequestMethods.Ftp.ListDirectoryDetails;
130             var statusCode = FtpStatusCode.DataAlreadyOpen;
131             FtpWebResponse response= callFtp(method);
132             return ReadByLine(response, statusCode, out isOk);
133         }
134 
135         /// 
136         /// 设置上级目录
137         /// 
138         public void SetPrePath()
139         {
140             string relatePath = this.RelatePath;
141             if (string.IsNullOrEmpty(relatePath) || relatePath.LastIndexOf("/") == 0 )
142             {
143                 relatePath = "";
144             }
145             else {
146                 relatePath = relatePath.Substring(0, relatePath.LastIndexOf("/"));
147             }
148             this.RelatePath = relatePath;
149         }
150 
151         #endregion
152 
153         #region 私有方法
154 
155         /// 
156         /// 调用Ftp,将命令发往Ftp并返回信息
157         /// 
158         /// 要发往Ftp的命令
159         /// 
160         private FtpWebResponse callFtp(string method)
161         {
162             string uri = string.Format("ftp://{0}:{1}{2}", this.IpAddr, this.Port, this.RelatePath);
163             FtpWebRequest request; request = (FtpWebRequest)FtpWebRequest.Create(uri);
164             request.UseBinary = true;
165             request.UsePassive = true;
166             request.Credentials = new NetworkCredential(UserName, Password);
167             request.KeepAlive = false;
168             request.Method = method;
169             FtpWebResponse response = (FtpWebResponse)request.GetResponse();
170             return response;
171         }
172 
173         /// 
174         /// 按行读取
175         /// 
176         /// 
177         /// 
178         /// 
179         /// 
180         private string[] ReadByLine(FtpWebResponse response, FtpStatusCode statusCode,out bool isOk) {
181             List<string> lstAccpet = new List<string>();
182             int i = 0;
183             while (true)
184             {
185                 if (response.StatusCode == statusCode)
186                 {
187                     using (StreamReader sr = new StreamReader(response.GetResponseStream()))
188                     {
189                         string line = sr.ReadLine();
190                         while (!string.IsNullOrEmpty(line))
191                         {
192                             lstAccpet.Add(line);
193                             line = sr.ReadLine();
194                         }
195                     }
196                     isOk = true;
197                     break;
198                 }
199                 i++;
200                 if (i > 10)
201                 {
202                     isOk = false;
203                     break;
204                 }
205                 Thread.Sleep(200);
206             }
207             response.Close();
208             return lstAccpet.ToArray();
209         }
210 
211         private void ReadByBytes(string filePath,FtpWebResponse response, FtpStatusCode statusCode, out bool isOk)
212         {
213             isOk = false;
214             int i = 0;
215             while (true)
216 
217             {
218                 if (response.StatusCode == statusCode)
219                 {
220                     long length = response.ContentLength;
221                     int bufferSize = 2048;
222                     int readCount;
223                     byte[] buffer = new byte[bufferSize];
224                     using (FileStream outputStream = new FileStream(filePath, FileMode.Create))
225                     {
226 
227                         using (Stream ftpStream = response.GetResponseStream())
228                         {
229                             readCount = ftpStream.Read(buffer, 0, bufferSize);
230                             while (readCount > 0)
231                             {
232                                 outputStream.Write(buffer, 0, readCount);
233                                 readCount = ftpStream.Read(buffer, 0, bufferSize);
234                             }
235                         }
236                     }
237                     break;
238                 }
239                 i++;
240                 if (i > 10)
241                 {
242                     isOk = false;
243                     break;
244                 }
245                 Thread.Sleep(200);
246             }
247             response.Close();
248         }
249         #endregion
250     }
251 
252     /// 
253     /// Ftp内容类型枚举
254     /// 
255     public enum FtpContentType
256     {
257         undefined = 0,
258         file = 1,
259         folder = 2
260     }
261 }

FTP服务端和客户端示意图

---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
源码链接如下:

源码下载

相关