好久不见,我又回来了。
给大家分享一个我最近使用c#代码操作ftp服务器的代码示例:
1 public abstract class FtpOperation 2 { 3 /// <summary> 4 /// FTP服务器地址 5 /// </summary> 6 private string ftpServer; 7 8 /// <summary> 9 /// 用户名 10 /// </summary> 11 private string userName; 12 13 /// <summary> 14 /// 密码 15 /// </summary> 16 private string passWord; 17 18 /// <summary> 19 /// FTPHelper类的构造函数 20 /// </summary> 21 /// <param name="ftpServer">FTP服务器地址</param> 22 /// <param name="userName">用户名</param> 23 /// <param name="passWord">密码</param> 24 public FtpOperation(string ftpServer, string userName, string passWord) 25 { 26 this.ftpServer = ftpServer; 27 this.userName = userName; 28 this.passWord = passWord; 29 } 30 31 /// <summary> 32 /// 执行FTP操作的方法 33 /// </summary> 34 /// <param name="action">要执行的操作</param> 35 private void ExecuteFtpOperation(Action action) 36 { 37 try 38 { 39 action.Invoke(); 40 } 41 catch (WebException ex) 42 { 43 if (ex.Status == WebExceptionStatus.Timeout) 44 { 45 Console.WriteLine("连接超时。"); 46 } 47 else 48 { 49 Console.WriteLine("发生错误 WebException: {0}", ex.Message); 50 } 51 } 52 catch (Exception ex) 53 { 54 Console.WriteLine("发生错误: {0}", ex.Message); 55 } 56 } 57 } 58 }基础类的构造函数和属性
1 /// <summary> 2 /// 执行FTP操作的方法 3 /// </summary> 4 /// <param name="action">要执行的操作</param> 5 private void ExecuteFtpOperation(Action action) 6 { 7 try 8 { 9 action.Invoke(); 10 } 11 catch (WebException ex) 12 { 13 if (ex.Status == WebExceptionStatus.Timeout) 14 { 15 Console.WriteLine("连接超时。"); 16 } 17 else 18 { 19 Console.WriteLine("发生错误 WebException: {0}", ex.Message); 20 } 21 } 22 catch (Exception ex) 23 { 24 Console.WriteLine("发生错误: {0}", ex.Message); 25 } 26 } 27 28 #region 文件查询 29 30 /// <summary> 31 /// 递归查询FTP服务器上所有文件和目录 32 /// </summary> 33 /// <param name="ftpDirectoryPath">要查询的目录路径</param> 34 public virtual List<FileInfo> RecursiveQueryAll(string ftpDirectoryPath = "") 35 { 36 List<FileInfo> list = new List<FileInfo>(); 37 ExecuteFtpOperation(() => 38 { 39 List<FileInfo> currentList = QueryAll(ftpDirectoryPath); 40 list.AddRange(currentList); 41 42 foreach (var fileInfo in currentList) 43 { 44 if (fileInfo.FileType == "Folder") 45 { 46 // 如果是文件夹,递归查询 47 List<FileInfo> subList = RecursiveQueryAll(ftpDirectoryPath + "/" + fileInfo.FileName); 48 list.AddRange(subList); 49 } 50 } 51 }); 52 return list; 53 } 54 55 /// <summary> 56 /// 查询FTP服务器上所有文件和目录 57 /// </summary> 58 /// <param name="ftpDirectoryPath">要查询的目录路径</param> 59 public virtual List<FileInfo> QueryAll(string ftpDirectoryPath = "") 60 { 61 List<FileInfo> list = new List<FileInfo>(); 62 ExecuteFtpOperation(() => 63 { 64 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + ftpDirectoryPath); 65 request.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 66 request.Credentials = new NetworkCredential(userName, passWord); 67 request.Timeout = 5000; 68 69 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 70 { 71 //Console.WriteLine("状态: {0}", response.StatusDescription); 72 73 using (var responseStream = response.GetResponseStream()) 74 { 75 if (responseStream != null) 76 { 77 using (var reader = new StreamReader(responseStream)) 78 { 79 string line = reader.ReadLine(); 80 while (!string.IsNullOrEmpty(line)) 81 { 82 list.AddRange(ParseFTPFileList(line)); 83 line = reader.ReadLine(); 84 } 85 } 86 } 87 } 88 } 89 }); 90 return list; 91 } 92 93 /// <summary> 94 /// 解析FTP服务器返回的文件列表信息,将其转换为FileInfo对象列表 95 /// </summary> 96 /// <param name="ftpFileList">FTP服务器返回的文件列表信息</param> 97 /// <returns>包含文件信息的FileInfo对象列表</returns> 98 public virtual List<FileInfo> ParseFTPFileList(string ftpFileList) 99 { 100 // 解析FTP返回的文件列表信息并返回FileInfo对象列表 101 List<FileInfo> filesInfo = new List<FileInfo>(); 102 103 // 按行分割FTP文件列表信息 104 string[] lines = ftpFileList.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); 105 106 foreach (string line in lines) 107 { 108 // 按空格分割行信息 109 string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 110 111 if (parts.Length >= 4) 112 { 113 114 string lastModifiedDateStr = parts[0] + " " + parts[1]; 115 string format = "MM-dd-yy hh:mmtt"; // 指定日期时间的确切格式 116 DateTime lastModifiedDate; 117 DateTime.TryParseExact(lastModifiedDateStr, format, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out lastModifiedDate); 118 119 // 提取文件大小信息 120 string fileSizeStr = parts[2]; 121 long fileSize; 122 string fileType = "Folder"; 123 string fileName = string.Join(" ", parts, 3, parts.Length - 3); 124 if (fileSizeStr.Contains("DIR")) 125 { 126 127 fileSize = 0; 128 } 129 else 130 { 131 fileType = Path.GetExtension(fileName); 132 fileSize = Convert.ToInt64(fileSizeStr); 133 } 134 135 136 FileInfo fileInfo = new FileInfo(lastModifiedDate, fileSize, fileType, fileName); 137 138 filesInfo.Add(fileInfo); 139 } 140 } 141 142 return filesInfo; 143 } 144 #endregion 145 146 #region 判断FTP服务器上是否存在指定文件夹 && 在FTP服务器上创建文件夹 &&删除FTP服务器上的空文件夹 147 /// <summary> 148 /// 判断FTP服务器上是否存在指定文件夹 149 /// </summary> 150 /// <param name="directoryPath">要检查的文件夹路径</param> 151 /// <returns>文件夹是否存在的布尔值</returns> 152 public virtual bool FtpDirectoryExists(string directoryPath) 153 { 154 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + directoryPath); 155 request.Credentials = new NetworkCredential(userName, passWord); 156 request.Method = WebRequestMethods.Ftp.ListDirectory; 157 158 try 159 { 160 FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 161 response.Close(); 162 return true; 163 } 164 catch (WebException ex) 165 { 166 FtpWebResponse response = (FtpWebResponse)ex.Response; 167 if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) 168 { 169 return false; 170 } 171 throw; 172 } 173 } 174 175 /// <summary> 176 /// 在FTP服务器上创建文件夹 177 /// </summary> 178 /// <param name="folderName">要创建的文件夹名称</param> 179 public virtual void FtpCreateDirectory(string folderName) 180 { 181 ExecuteFtpOperation(() => 182 { 183 string[] pathArray = folderName.Split('/'); 184 var tempPath = ""; 185 foreach (var path in pathArray) 186 { 187 if (path == "") 188 { 189 continue; 190 } 191 tempPath += path + "/"; 192 if (FtpDirectoryExists(tempPath)) 193 { 194 continue; 195 } 196 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + tempPath); 197 request.Method = WebRequestMethods.Ftp.MakeDirectory; 198 request.Credentials = new NetworkCredential(userName, passWord); 199 200 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 201 { 202 Console.WriteLine($"文件夹{path}创建成功。"); 203 } 204 } 205 206 }); 207 } 208 /// <summary> 209 /// 删除FTP服务器上的空文件夹 210 /// </summary> 211 /// <param name="ftpFolderPath">FTP服务器上的空文件夹路径</param> 212 public virtual void FtpDeleteFolder(string ftpFolderPath) 213 { 214 ExecuteFtpOperation(() => 215 { 216 if (string.IsNullOrEmpty(ftpFolderPath)) 217 { 218 return; 219 } 220 // 连接到 FTP 服务器 221 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + ftpFolderPath); 222 request.Credentials = new NetworkCredential(userName, passWord); 223 request.Method = WebRequestMethods.Ftp.RemoveDirectory; 224 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 225 { 226 Console.WriteLine($"文件夹{new DirectoryInfo(ftpFolderPath).Name}删除成功!"); 227 } 228 }); 229 } 230 #endregion 231 232 #region 文件、文件夹删除 233 /// <summary> 234 /// 删除FTP服务器指定路径下的多个文件 235 /// </summary> 236 /// <param name="directoryPath">要删除文件的目录路径</param> 237 /// <param name="fileNames">要删除的文件名数组</param> 238 public virtual void FtpDeleteFiles(string directoryPath, string[] fileNames) 239 { 240 ExecuteFtpOperation(() => 241 { 242 foreach (var fileName in fileNames) 243 { 244 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + directoryPath + "/" + fileName); 245 request.Method = WebRequestMethods.Ftp.DeleteFile; 246 request.Credentials = new NetworkCredential(userName, passWord); 247 248 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 249 { 250 Console.WriteLine($"文件 '{fileName}' 删除成功。"); 251 } 252 } 253 }); 254 } 255 256 /// <summary> 257 /// 递归删除FTP服务器上的文件夹及其内容 258 /// </summary> 259 /// <param name="directoryPath">要删除的文件夹路径</param> 260 public virtual void FtpDeleteFolders(string directoryPath) 261 { 262 ExecuteFtpOperation(() => 263 { 264 265 if (!FtpDirectoryExists(directoryPath)) 266 { 267 Console.WriteLine($"{directoryPath} 不存在!"); 268 return; 269 } 270 271 // 获取文件夹内所有文件和子文件夹 272 var fileList = QueryAll(directoryPath); 273 foreach (var fileInfo in fileList) 274 { 275 // 删除文件 276 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + directoryPath + "/" + fileInfo.FileName); 277 request.Method = WebRequestMethods.Ftp.DeleteFile; 278 request.Credentials = new NetworkCredential(userName, passWord); 279 280 // 如果是文件夹,递归删除 281 if (fileInfo.FileType == "Folder") 282 { 283 FtpDeleteFolders(directoryPath + "/" + fileInfo.FileName); 284 } 285 else 286 { 287 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 288 { 289 Console.WriteLine($"文件 '{fileInfo.FileName}' 删除成功。"); 290 } 291 } 292 293 294 295 } 296 297 // 删除空文件夹 298 FtpDeleteFolder(directoryPath); 299 }); 300 } 301 302 303 #endregion 304 305 #region 文件移动 306 307 /// <summary> 308 /// 移动FTP服务器上的多个文件 309 /// </summary> 310 /// <param name="sourceDirectoryPath">源文件目录路径</param> 311 /// <param name="destinationDirectoryPath">目标文件目录路径</param> 312 /// <param name="fileNames">要移动的文件名数组</param> 313 public virtual void FtpMoveFiles(string sourceDirectoryPath, string destinationDirectoryPath, string[] fileNames) 314 { 315 ExecuteFtpOperation(() => 316 { 317 if (!FtpDirectoryExists(sourceDirectoryPath)) 318 { 319 Console.WriteLine($"{sourceDirectoryPath} 目录不存在!"); 320 return; 321 } 322 if (!FtpDirectoryExists(destinationDirectoryPath)) 323 { 324 FtpCreateDirectory(destinationDirectoryPath); 325 } 326 foreach (var fileName in fileNames) 327 { 328 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + sourceDirectoryPath + "/" + fileName); 329 request.Method = WebRequestMethods.Ftp.Rename; 330 request.Credentials = new NetworkCredential(userName, passWord); 331 request.RenameTo = destinationDirectoryPath + "/" + fileName; 332 333 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 334 { 335 Console.WriteLine($"文件 '{fileName}' 移动成功。"); 336 } 337 } 338 }); 339 } 340 341 /// <summary> 342 /// 移动整个文件夹到目标位置 343 /// </summary> 344 /// <param name="sourceDirectoryPath">源文件夹路径</param> 345 /// <param name="destinationDirectoryPath">目标文件夹路径</param> 346 public virtual void FtpMoveFolder(string sourceDirectoryPath, string destinationDirectoryPath) 347 { 348 ExecuteFtpOperation(() => 349 { 350 if (!FtpDirectoryExists(sourceDirectoryPath)) 351 { 352 Console.WriteLine($"{sourceDirectoryPath} 目录不存在!"); 353 return; 354 } 355 //destinationDirectoryPath = destinationDirectoryPath + "/" + new DirectoryInfo(sourceDirectoryPath).Name;//解决移动后源文件夹丢失的问题 356 // 创建目标文件夹 357 if (!FtpDirectoryExists(destinationDirectoryPath)) 358 { 359 FtpCreateDirectory(destinationDirectoryPath); 360 } 361 362 363 // 获取源文件夹内所有文件和子文件夹 364 var fileList = QueryAll(sourceDirectoryPath); 365 foreach (var fileInfo in fileList) 366 { 367 // 构建源文件和目标文件的完整路径 368 string sourcePath = sourceDirectoryPath + "/" + fileInfo.FileName; 369 string destinationPath = destinationDirectoryPath + "/" + fileInfo.FileName; 370 371 // 如果是文件夹,递归移动 372 if (fileInfo.FileType == "Folder") 373 { 374 FtpMoveFolder(sourcePath, destinationPath); 375 } 376 else 377 { 378 // 创建源文件的FTP请求 379 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpServer + sourcePath); 380 request.Method = WebRequestMethods.Ftp.Rename; // 使用重命名操作实现移动 381 request.Credentials = new NetworkCredential(userName, passWord); 382 request.RenameTo = destinationPath; // 设置重命名目标路径 383 384 // 发起请求并获取响应 385 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 386 { 387 Console.WriteLine($"文件 '{fileInfo.FileName}' 移动成功。"); 388 } 389 } 390 } 391 if (!string.IsNullOrEmpty(sourceDirectoryPath)) 392 { 393 // 删除源文件夹 394 FtpDeleteFolder(sourceDirectoryPath); 395 } 396 397 }); 398 } 399 400 #endregion 401 402 #region 文件上传【文件批量上传&&文件夹上传】 403 /// <summary> 404 /// 上传文件到FTP服务器 405 /// </summary> 406 /// <param name="filePath">要上传的文件路径</param> 407 /// <param name="directoryPath">目标文件夹路径</param> 408 public virtual void FtpUploadFile(string filePath, string directoryPath = "") 409 { 410 ExecuteFtpOperation(() => 411 { 412 if (!FtpDirectoryExists(directoryPath)) 413 { 414 FtpCreateDirectory(directoryPath); 415 } 416 using (WebClient client = new WebClient()) 417 { 418 client.Credentials = new NetworkCredential(userName, passWord); ; 419 client.UploadFile(ftpServer + directoryPath + "/" + Path.GetFileName(filePath), WebRequestMethods.Ftp.UploadFile, filePath); 420 Console.WriteLine($"{filePath}文件上传成功。"); 421 } 422 }); 423 } 424 /// <summary> 425 /// 递归上传文件夹到FTP服务器 426 /// </summary> 427 /// <param name="localFolderPath">本地文件夹路径</param> 428 /// <param name="ftpDirectoryPath">FTP服务器目标文件夹路径</param> 429 public virtual void FtpUploadFolder(string localFolderPath, string ftpDirectoryPath) 430 { 431 // 检查本地文件夹是否存在 432 if (!Directory.Exists(localFolderPath)) 433 { 434 Console.WriteLine("本地文件夹不存在。"); 435 return; 436 } 437 438 // 获取文件夹名称 439 string folderName = new DirectoryInfo(localFolderPath).Name; 440 441 // 构建FTP服务器上的目标路径 442 string rootPath = (string.IsNullOrEmpty(ftpDirectoryPath) ? "" : ftpDirectoryPath + "/"); 443 444 // 如果目标文件夹在FTP服务器上不存在,则创建 445 if (!FtpDirectoryExists(rootPath + folderName)) 446 { 447 FtpCreateDirectory(rootPath + folderName); 448 } 449 450 // 获取文件夹中的所有文件 451 string[] files = Directory.GetFiles(localFolderPath); 452 453 // 逐个上传文件 454 foreach (string file in files) 455 { 456 FtpUploadFile(file, rootPath + folderName); 457 } 458 459 // 获取文件夹中的所有子文件夹 460 string[] subDirectories = Directory.GetDirectories(localFolderPath); 461 462 // 逐个处理子文件夹 463 foreach (string subDirectory in subDirectories) 464 { 465 // 递归上传子文件夹 466 FtpUploadFolder(subDirectory, rootPath + folderName); 467 } 468 469 Console.WriteLine($"{localFolderPath} 文件夹上传成功。"); 470 } 471 472 /// <summary> 473 /// 上传多个文件夹到FTP服务器 474 /// </summary> 475 /// <param name="filePath">要上传的文件夹路径</param> 476 /// <param name="ftpDirectoryPath">目标文件夹路径</param> 477 public virtual void FtpUploadFolders(string[] localDirectories, string ftpDirectoryPath = "") 478 { 479 foreach (string localDirectory in localDirectories) 480 { 481 FtpUploadFolder(localDirectory, ftpDirectoryPath); 482 } 483 } 484 #endregion 485 486 #region 文件下载 487 /// <summary> 488 /// 从FTP服务器下载文件到本地 489 /// </summary> 490 /// <param name="remoteFilePaths">要下载的远程文件路径数组</param> 491 /// <param name="localDirectory">本地目录路径</param> 492 public virtual void FtpDownloadFile(string[] remoteFilePaths, string localDirectory) 493 { 494 ExecuteFtpOperation(() => 495 { 496 // 检查本地路径是否存在,如果不存在则创建 497 if (!Directory.Exists(localDirectory)) 498 { 499 Directory.CreateDirectory(localDirectory); 500 } 501 using (WebClient client = new WebClient()) 502 { 503 client.Credentials = new NetworkCredential(userName, passWord); 504 505 foreach (var remoteFilePath in remoteFilePaths) 506 { 507 string fileName = remoteFilePath.Substring(remoteFilePath.LastIndexOf("/") + 1); 508 string localFilePath = Path.Combine(localDirectory, fileName); 509 510 try 511 { 512 client.DownloadFile(ftpServer + remoteFilePath, localFilePath); 513 Console.WriteLine($"文件 '{fileName}' 下载成功。"); 514 } 515 catch (WebException ex) 516 { 517 Console.WriteLine($"下载文件 '{fileName}' 时出错: {ex.Message}"); 518 // Handle the exception as needed 519 } 520 } 521 } 522 }); 523 } 524 525 /// <summary> 526 /// 递归从FTP服务器下载文件夹到本地 527 /// </summary> 528 /// <param name="remoteDirectoryPath">要下载的远程文件夹路径</param> 529 /// <param name="localDirectory">本地目录路径</param> 530 public virtual void FtpDownloadFolder(string remoteDirectoryPath, string localDirectory) 531 { 532 ExecuteFtpOperation(() => 533 { 534 // 检查本地路径是否存在,如果不存在则创建 535 if (!Directory.Exists(localDirectory)) 536 { 537 Directory.CreateDirectory(localDirectory); 538 } 539 // 获取远程文件夹内所有文件和子文件夹 540 var fileList = QueryAll(remoteDirectoryPath); 541 542 foreach (var fileInfo in fileList) 543 { 544 string remotePath = remoteDirectoryPath + "/" + fileInfo.FileName; 545 string localPath = Path.Combine(localDirectory, fileInfo.FileName); 546 547 if (fileInfo.FileType == "Folder") 548 { 549 // 如果是文件夹,递归下载 550 string newLocalDirectory = Path.Combine(localDirectory, fileInfo.FileName); 551 Directory.CreateDirectory(newLocalDirectory); 552 FtpDownloadFolder(remotePath, newLocalDirectory); 553 } 554 else 555 { 556 // 如果是文件,下载到本地 557 using (WebClient client = new WebClient()) 558 { 559 client.Credentials = new NetworkCredential(userName, passWord); 560 client.DownloadFile(ftpServer + remotePath, localPath); 561 Console.WriteLine($"文件 '{fileInfo.FileName}' 下载成功。"); 562 } 563 } 564 } 565 }); 566 } 567 568 #endregionFtpOperation 中其他的方法
调用示例
// FTP 服务器地址 string ftpServer = "ftp://127.0.0.1:27/"; // FTP 服务器用户名 string userName = "Administrator"; // FTP 服务器密码 string password = "admin"; FtpTest ftp = new FtpTest(ftpServer, userName, password); //ftp.QueryAll("/Template"); //查询 ftp.FtpDeleteFolders("");//删除所有 ftp.FtpUploadFolder("e:\\CoaTemplate", "");//将文件夹的内容上传到根目录 ftp.FtpUploadFolder(@"D:\GitCode\Blog.Core", "/gitCode/Blog.Core");//将本地文件夹的内容上传到指定目录 var data = ftp.RecursiveQueryAll("");//查询所有文件信息 ftp.FtpMoveFolder("/Template", "/1/Template");//文件夹移动 ftp.FtpDownloadFolder("/1", "d:\\1\\"); //将ftp服务器的指定文件夹下载到本地目录
贴了半天代码,都不太行,一会能展开,一会展不开,源码地址放下面了。
项目地址:https://github.com/yycb1994/FtpSiteManager