C# - VS2019WinFrm桌面应用程序FtpClient实现
前言
本篇主要记录:VS2019 WinFrm桌面应用程序实现简单的FtpClient,包含Ftp文件查看、上传和下载等功能。
准备工作
搭建WinFrm前台界面
添加必要的控件,这里主要应用到GroupBox、Label、TextBox和Button,如下图
核心代码
构造FtpHelper类
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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.Tasks; 8 9 namespace FtpClientTest 10 { 11 public class FtpHelper 12 { 13 // FTP连接地址 14 string ftpServerIP; 15 // 指定FTP连接成功后的当前目录, 如果不指定即默认为根目录 16 string ftpRemotePath; 17 // 用户名 18 string ftpUserID; 19 // 密码 20 string ftpPassword; 21 // 通用处理路径 22 string ftpURI; 23 24 /// <summary> 25 /// 连接FTP 26 /// </summary> 27 /// <param name="FtpServerIP">FTP连接地址</param> 28 /// <param name="FtpRemotePath">指定FTP连接成功后的当前目录, 如果不指定即默认为根目录</param> 29 /// <param name="FtpUserID">用户名</param> 30 /// <param name="FtpPassword">密码</param> 31 public FtpHelper(string FtpServerIP, string FtpRemotePath, string FtpUserID, string FtpPassword) 32 { 33 ftpServerIP = FtpServerIP; 34 ftpRemotePath = FtpRemotePath; 35 ftpUserID = FtpUserID; 36 ftpPassword = FtpPassword; 37 ftpURI = "ftp://" + ftpServerIP + "/" + ftpRemotePath + "/"; 38 } 39 40 /// <summary> 41 /// 上传 42 /// </summary> 43 /// <param name="filename">本地文件全路径</param> 44 public void Upload(string filename) 45 { 46 FileInfo fileInf = new FileInfo(filename); 47 string uri = ftpURI + fileInf.Name; 48 FtpWebRequest reqFTP; 49 50 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 51 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 52 reqFTP.KeepAlive = false; 53 reqFTP.Method = WebRequestMethods.Ftp.UploadFile; 54 reqFTP.UseBinary = true; 55 reqFTP.UsePassive = false; 56 reqFTP.ContentLength = fileInf.Length; 57 int buffLength = 2048; 58 byte[] buff = new byte[buffLength]; 59 int contentLen; 60 FileStream fs = fileInf.OpenRead(); 61 try 62 { 63 Stream strm = reqFTP.GetRequestStream(); 64 contentLen = fs.Read(buff, 0, buffLength); 65 while (contentLen != 0) 66 { 67 strm.Write(buff, 0, contentLen); 68 contentLen = fs.Read(buff, 0, buffLength); 69 } 70 strm.Close(); 71 fs.Close(); 72 } 73 catch (Exception ex) 74 { 75 throw new Exception("Ftphelper Upload Error --> " + ex.Message); 76 } 77 } 78 79 /// <summary> 80 /// 下载 81 /// </summary> 82 /// <param name="filePath">文件保存本地路径</param> 83 /// <param name="fileName">Ftp上文件的路径</param> 84 public void Download(string filePath, string fileName) 85 { 86 FtpWebRequest reqFTP; 87 try 88 { 89 FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create); 90 91 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + fileName)); 92 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; 93 reqFTP.UseBinary = true; 94 reqFTP.UsePassive = false; 95 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 96 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 97 Stream ftpStream = response.GetResponseStream(); 98 long cl = response.ContentLength; 99 int bufferSize = 2048; 100 int readCount; 101 byte[] buffer = new byte[bufferSize]; 102 103 readCount = ftpStream.Read(buffer, 0, bufferSize); 104 while (readCount > 0) 105 { 106 outputStream.Write(buffer, 0, readCount); 107 readCount = ftpStream.Read(buffer, 0, bufferSize); 108 } 109 110 ftpStream.Close(); 111 outputStream.Close(); 112 response.Close(); 113 } 114 catch (Exception ex) 115 { 116 throw new Exception("FtpHelper Download Error --> " + ex.Message); 117 } 118 } 119 120 /// <summary> 121 /// 删除文件 122 /// </summary> 123 /// <param name="fileName">Ftp上文件的名称</param> 124 public void Delete(string fileName) 125 { 126 try 127 { 128 string uri = ftpURI + fileName; 129 FtpWebRequest reqFTP; 130 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 131 132 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 133 reqFTP.KeepAlive = false; 134 reqFTP.Method = WebRequestMethods.Ftp.DeleteFile; 135 reqFTP.UsePassive = false; 136 137 string result = String.Empty; 138 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 139 long size = response.ContentLength; 140 Stream datastream = response.GetResponseStream(); 141 StreamReader sr = new StreamReader(datastream); 142 result = sr.ReadToEnd(); 143 sr.Close(); 144 datastream.Close(); 145 response.Close(); 146 } 147 catch (Exception ex) 148 { 149 throw new Exception("FtpHelper Delete Error --> " + ex.Message + " 文件名:" + fileName); 150 } 151 } 152 153 /// <summary> 154 /// 删除文件夹 155 /// </summary> 156 /// <param name="folderName">Ftp上文件夹的名称</param> 157 public void RemoveDirectory(string folderName) 158 { 159 try 160 { 161 string uri = ftpURI + folderName; 162 FtpWebRequest reqFTP; 163 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 164 165 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 166 reqFTP.KeepAlive = false; 167 reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory; 168 reqFTP.UsePassive = false; 169 170 string result = String.Empty; 171 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 172 long size = response.ContentLength; 173 Stream datastream = response.GetResponseStream(); 174 StreamReader sr = new StreamReader(datastream); 175 result = sr.ReadToEnd(); 176 sr.Close(); 177 datastream.Close(); 178 response.Close(); 179 } 180 catch (Exception ex) 181 { 182 throw new Exception("FtpHelper Delete Error --> " + ex.Message + " 文件名:" + folderName); 183 } 184 } 185 186 /// <summary> 187 /// 获取当前目录下明细(包含文件和文件夹) 188 /// </summary> 189 /// <returns></returns> 190 public string[] GetFilesDetailList() 191 { 192 string[] downloadFiles; 193 try 194 { 195 StringBuilder result = new StringBuilder(); 196 FtpWebRequest ftp; 197 ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI)); 198 ftp.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 199 ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 200 ftp.UsePassive = false; 201 WebResponse response = ftp.GetResponse(); 202 StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default); 203 204 //while (reader.Read() > 0) 205 //{ 206 207 //} 208 string line = reader.ReadLine(); 209 //line = reader.ReadLine(); 210 //line = reader.ReadLine(); 211 212 while (line != null) 213 { 214 result.Append(line); 215 result.Append("\n"); 216 line = reader.ReadLine(); 217 } 218 result.Remove(result.ToString().LastIndexOf("\n"), 1); 219 reader.Close(); 220 response.Close(); 221 return result.ToString().Split('\n'); 222 } 223 catch (Exception ex) 224 { 225 downloadFiles = null; 226 throw new Exception("FtpHelper Error --> " + ex.Message); 227 } 228 } 229 230 /// <summary> 231 /// 获取当前目录下文件列表(仅文件) 232 /// </summary> 233 /// <returns></returns> 234 public string[] GetFileList(string mask) 235 { 236 string[] downloadFiles; 237 StringBuilder result = new StringBuilder(); 238 FtpWebRequest reqFTP; 239 try 240 { 241 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI)); 242 reqFTP.UseBinary = true; 243 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 244 reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; 245 reqFTP.UsePassive = false; 246 WebResponse response = reqFTP.GetResponse(); 247 StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default); 248 249 string line = reader.ReadLine(); 250 while (line != null) 251 { 252 if (mask.Trim() != string.Empty && mask.Trim() != "*.*") 253 { 254 255 string mask_ = mask.Substring(0, mask.IndexOf("*")); 256 if (line.Substring(0, mask_.Length) == mask_) 257 { 258 result.Append(line); 259 result.Append("\n"); 260 } 261 } 262 else 263 { 264 result.Append(line); 265 result.Append("\n"); 266 } 267 line = reader.ReadLine(); 268 } 269 result.Remove(result.ToString().LastIndexOf('\n'), 1); 270 reader.Close(); 271 response.Close(); 272 return result.ToString().Split('\n'); 273 } 274 catch (Exception ex) 275 { 276 downloadFiles = null; 277 if (ex.Message.Trim() != "远程服务器返回错误: (550) 文件不可用(例如,未找到文件,无法访问文件)。") 278 { 279 throw new Exception("FtpHelper GetFileList Error --> " + ex.Message.ToString()); 280 } 281 return downloadFiles; 282 } 283 } 284 285 /// <summary> 286 /// 获取当前目录下所有的文件夹列表(仅文件夹) 287 /// </summary> 288 /// <returns></returns> 289 public string[] GetDirectoryList() 290 { 291 string[] drectory = GetFilesDetailList(); 292 string m = string.Empty; 293 foreach (string str in drectory) 294 { 295 int dirPos = str.IndexOf("<DIR>"); 296 if (dirPos > 0) 297 { 298 /*判断 Windows 风格*/ 299 m += str.Substring(dirPos + 5).Trim() + "\n"; 300 } 301 else if (str.Trim().Substring(0, 1).ToUpper() == "D") 302 { 303 /*判断 Unix 风格*/ 304 string dir = str.Substring(54).Trim(); 305 if (dir != "." && dir != "..") 306 { 307 m += dir + "\n"; 308 } 309 } 310 } 311 312 char[] n = new char[] { '\n' }; 313 return m.Split(n); 314 } 315 316 /// <summary> 317 /// 判断当前目录下指定的子目录是否存在 318 /// </summary> 319 /// <param name="RemoteDirectoryName">指定的目录名</param> 320 public bool DirectoryExist(string RemoteDirectoryName) 321 { 322 string[] dirList = GetDirectoryList(); 323 foreach (string str in dirList) 324 { 325 if (str.Trim() == RemoteDirectoryName.Trim()) 326 { 327 return true; 328 } 329 } 330 return false; 331 } 332 333 /// <summary> 334 /// 判断当前目录下指定的文件是否存在 335 /// </summary> 336 /// <param name="RemoteFileName">远程文件名</param> 337 public bool FileExist(string RemoteFileName) 338 { 339 string[] fileList = GetFileList("*.*"); 340 foreach (string str in fileList) 341 { 342 if (str.Trim() == RemoteFileName.Trim()) 343 { 344 return true; 345 } 346 } 347 return false; 348 } 349 350 /// <summary> 351 /// 创建文件夹 352 /// </summary> 353 /// <param name="dirName"></param> 354 public void MakeDir(string dirName) 355 { 356 FtpWebRequest reqFTP; 357 try 358 { 359 // dirName = name of the directory to create. 360 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + dirName)); 361 reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory; 362 reqFTP.UseBinary = true; 363 reqFTP.UsePassive = false; 364 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 365 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 366 Stream ftpStream = response.GetResponseStream(); 367 368 ftpStream.Close(); 369 response.Close(); 370 } 371 catch (Exception ex) 372 { 373 throw new Exception("FtpHelper MakeDir Error --> " + ex.Message); 374 } 375 } 376 377 /// <summary> 378 /// 获取指定文件大小 379 /// </summary> 380 /// <param name="filename"></param> 381 /// <returns></returns> 382 public long GetFileSize(string filename) 383 { 384 FtpWebRequest reqFTP; 385 long fileSize = 0; 386 try 387 { 388 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + filename)); 389 reqFTP.Method = WebRequestMethods.Ftp.GetFileSize; 390 reqFTP.UseBinary = true; 391 reqFTP.UsePassive = false; 392 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 393 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 394 Stream ftpStream = response.GetResponseStream(); 395 fileSize = response.ContentLength; 396 397 ftpStream.Close(); 398 response.Close(); 399 } 400 catch (Exception ex) 401 { 402 throw new Exception("FtpHelper GetFileSize Error --> " + ex.Message); 403 } 404 return fileSize; 405 } 406 407 /// <summary> 408 /// 改名 409 /// </summary> 410 /// <param name="currentFilename"></param> 411 /// <param name="newFilename"></param> 412 public void ReName(string currentFilename, string newFilename) 413 { 414 FtpWebRequest reqFTP; 415 try 416 { 417 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + currentFilename)); 418 reqFTP.Method = WebRequestMethods.Ftp.Rename; 419 reqFTP.RenameTo = newFilename; 420 reqFTP.UseBinary = true; 421 reqFTP.UsePassive = false; 422 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 423 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 424 Stream ftpStream = response.GetResponseStream(); 425 426 ftpStream.Close(); 427 response.Close(); 428 } 429 catch (Exception ex) 430 { 431 throw new Exception("FtpHelper ReName Error --> " + ex.Message); 432 } 433 } 434 435 /// <summary> 436 /// 移动文件 437 /// </summary> 438 /// <param name="currentFilename"></param> 439 /// <param name="newFilename"></param> 440 public void MovieFile(string currentFilename, string newDirectory) 441 { 442 ReName(currentFilename, newDirectory); 443 } 444 445 /// <summary> 446 /// 切换当前目录 447 /// </summary> 448 /// <param name="DirectoryName"></param> 449 /// <param name="IsRoot">true 绝对路径 false 相对路径</param> 450 public void GotoDirectory(string DirectoryName, bool IsRoot) 451 { 452 if (IsRoot) 453 { 454 ftpRemotePath = DirectoryName; 455 } 456 else 457 { 458 ftpRemotePath += DirectoryName + "/"; 459 } 460 ftpURI = "ftp://" + ftpServerIP + "/" + ftpRemotePath + "/"; 461 } 462 463 /// <summary> 464 /// 删除订单目录 465 /// </summary> 466 /// <param name="ftpServerIP">FTP 主机地址</param> 467 /// <param name="folderToDelete">FTP 用户名</param> 468 /// <param name="ftpUserID">FTP 用户名</param> 469 /// <param name="ftpPassword">FTP 密码</param> 470 public static void DeleteOrderDirectory(string ftpServerIP, string folderToDelete, string ftpUserID, string ftpPassword) 471 { 472 try 473 { 474 if (!string.IsNullOrEmpty(ftpServerIP) && !string.IsNullOrEmpty(folderToDelete) && !string.IsNullOrEmpty(ftpUserID) && !string.IsNullOrEmpty(ftpPassword)) 475 { 476 FtpHelper fw = new FtpHelper(ftpServerIP, folderToDelete, ftpUserID, ftpPassword); 477 //进入订单目录 478 fw.GotoDirectory(folderToDelete, true); 479 //获取规格目录 480 string[] folders = fw.GetDirectoryList(); 481 foreach (string folder in folders) 482 { 483 if (!string.IsNullOrEmpty(folder) || folder != "") 484 { 485 //进入订单目录 486 string subFolder = folderToDelete + "/" + folder; 487 fw.GotoDirectory(subFolder, true); 488 //获取文件列表 489 string[] files = fw.GetFileList("*.*"); 490 if (files != null) 491 { 492 //删除文件 493 foreach (string file in files) 494 { 495 fw.Delete(file); 496 } 497 } 498 //删除冲印规格文件夹 499 fw.GotoDirectory(folderToDelete, true); 500 fw.RemoveDirectory(folder); 501 } 502 } 503 504 //删除订单文件夹 505 string parentFolder = folderToDelete.Remove(folderToDelete.LastIndexOf('/')); 506 string orderFolder = folderToDelete.Substring(folderToDelete.LastIndexOf('/') + 1); 507 fw.GotoDirectory(parentFolder, true); 508 fw.RemoveDirectory(orderFolder); 509 } 510 else 511 { 512 throw new Exception("FTP 及路径不能为空!"); 513 } 514 } 515 catch (Exception ex) 516 { 517 throw new Exception("删除订单时发生错误,错误信息为:" + ex.Message); 518 } 519 } 520 } 521 }
配合控件重写Ftp方法
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.IO; 7 using System.Linq; 8 using System.Net; 9 using System.Text; 10 using System.Threading.Tasks; 11 using System.Windows.Forms; 12 13 namespace FtpClientTest 14 { 15 public partial class FrmMain : Form 16 { 17 public FrmMain() 18 { 19 InitializeComponent(); 20 } 21 22 // 定义全局变量 ftp参数 23 private FtpHelper ftpHelper; 24 private string ipAddr; 25 private string port; 26 private string path; 27 private string userName; 28 private string password; 29 30 /// <summary> 31 /// 方法:Ftp初始化 32 /// </summary> 33 private void FtpInit() 34 { 35 ipAddr = this.txtHost.Text; 36 port = this.txtHost.Text; 37 path = this.txtCurrentDir.Text; 38 userName = this.txtUserName.Text; 39 password = this.txtPassCode.Text; 40 ftpHelper = new FtpHelper(ipAddr, path, userName, password); 41 } 42 43 /// <summary> 44 /// 事件:文件下载 45 /// </summary> 46 /// <param name="sender"></param> 47 /// <param name="e"></param> 48 private void btnDownLoad_Click(object sender, EventArgs e) 49 { 50 try 51 { 52 ftpHelper.Download(@"D:\", this.txtFilePath.Text.Trim()); 53 MessageBox.Show("下载成功!", "提示"); 54 } 55 catch (Exception ex) 56 { 57 MessageBox.Show("下载失败!错误信息[" + ex.Message + "]", "警告"); 58 } 59 60 } 61 /// <summary> 62 /// 方法:获取Ftp当前目录下的文件 63 /// </summary> 64 private void GetFileList() 65 { 66 string[] str = ftpHelper.GetFilesDetailList(); 67 tbFileLists.Text = ""; 68 for (int i = 0; i < str.Length - 1; i++) 69 { 70 if (tbFileLists.Text.ToString() == "") 71 { 72 tbFileLists.Text = str[i]; 73 } 74 else 75 { 76 tbFileLists.Text = tbFileLists.Text + "\r\n" + str[i]; 77 } 78 } 79 } 80 81 /// <summary> 82 /// 事件:连接Ftp,获取文件列表 83 /// </summary> 84 /// <param name="sender"></param> 85 /// <param name="e"></param> 86 private void btnConnect_Click(object sender, EventArgs e) 87 { 88 try 89 { 90 FtpInit(); 91 this.btnDownLoad.Enabled = true; 92 this.btnUpload.Enabled = true; 93 this.btnOpen.Enabled = true; 94 GetFileList(); 95 } 96 catch (Exception ex) 97 { 98 this.btnDownLoad.Enabled = false; 99 this.btnUpload.Enabled = false; 100 this.btnOpen.Enabled = false; 101 MessageBox.Show("连接失败!错误信息[" + ex.Message + "]", "警告"); 102 } 103 } 104 105 /// <summary> 106 /// 事件:上传文件 107 /// </summary> 108 /// <param name="sender"></param> 109 /// <param name="e"></param> 110 private void btnUpload_Click(object sender, EventArgs e) 111 { 112 try 113 { 114 ftpHelper.Upload(this.txtLocalFilePath.Text.Trim()); 115 MessageBox.Show("上传成功!", "提示"); 116 } 117 catch (Exception ex) 118 { 119 MessageBox.Show("上传失败!错误信息[" + ex.Message + "]", "警告"); 120 } 121 } 122 123 /// <summary> 124 /// 事件:选中需要上传的文件 125 /// </summary> 126 /// <param name="sender"></param> 127 /// <param name="e"></param> 128 private void btnOpen_Click(object sender, EventArgs e) 129 { 130 // 创建 OpenFileDialog 对象 131 OpenFileDialog ofd = new OpenFileDialog(); 132 // 设定默认打开文件类型,删选、设定文件显示类型 133 ofd.Filter = "(*.et;*.xls;*.xlsx)|*.et;*.xls;*.xlsx|all|*.*"; 134 // 显示打开文件的窗口 135 ofd.ShowDialog(); 136 // 获得选择的文件路径,并赋值给 137 this.txtLocalFilePath.Text = ofd.FileName; 138 } 139 } 140 }
实现效果
作者:Jeremy.Wu
出处:https://www.cnblogs.com/jeremywucnblog/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。