FtpClient.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  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. namespace Masuit.Tools.Net
  8. {
  9. /// <summary>
  10. /// FTP客户端操作类
  11. /// </summary>
  12. public class FtpClient
  13. {
  14. #region 变量属性
  15. /// <summary>
  16. /// Ftp服务器ip
  17. /// </summary>
  18. private string FtpServer { get; set; }
  19. /// <summary>
  20. /// Ftp 指定用户名
  21. /// </summary>
  22. private string Username { get; set; }
  23. /// <summary>
  24. /// Ftp 指定用户密码
  25. /// </summary>
  26. private string Password { get; set; }
  27. #endregion
  28. /// <summary>
  29. /// 获取一个匿名登录的ftp客户端
  30. /// </summary>
  31. /// <param name="serverIp">服务器IP地址</param>
  32. /// <returns></returns>
  33. public static FtpClient GetAnonymousClient(string serverIp)
  34. {
  35. if (!serverIp.MatchInetAddress())
  36. {
  37. throw new ArgumentException("IP地址格式不正确");
  38. }
  39. return new FtpClient
  40. {
  41. FtpServer = serverIp
  42. };
  43. }
  44. /// <summary>
  45. /// 获取一个匿名登录的ftp客户端
  46. /// </summary>
  47. /// <param name="serverIp">服务器ip</param>
  48. /// <param name="username">用户名</param>
  49. /// <param name="password">密码</param>
  50. /// <returns></returns>
  51. public static FtpClient GetClient(string serverIp, string username, string password)
  52. {
  53. if (!serverIp.MatchInetAddress())
  54. {
  55. throw new ArgumentException("IP地址格式不正确");
  56. }
  57. return new FtpClient
  58. {
  59. FtpServer = serverIp,
  60. Username = username,
  61. Password = password
  62. };
  63. }
  64. #region 从FTP服务器下载文件,指定本地路径和本地文件名
  65. /// <summary>
  66. /// 从FTP服务器下载文件,指定本地路径和本地文件名
  67. /// </summary>
  68. /// <param name="remoteFileName">远程文件名</param>
  69. /// <param name="localFileName">保存本地的文件名(包含路径)</param>
  70. /// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
  71. /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
  72. public void Download(string remoteFileName, string localFileName, bool ifCredential = false, Action<int, int> updateProgress = null)
  73. {
  74. using var outputStream = new FileStream(localFileName, FileMode.Create);
  75. if (FtpServer == null || FtpServer.Trim().Length == 0)
  76. {
  77. throw new Exception("ftp下载目标服务器地址未设置!");
  78. }
  79. Uri uri = new Uri("ftp://" + FtpServer + "/" + remoteFileName);
  80. var ftpsize = (FtpWebRequest)WebRequest.Create(uri);
  81. ftpsize.UseBinary = true;
  82. var reqFtp = (FtpWebRequest)WebRequest.Create(uri);
  83. reqFtp.UseBinary = true;
  84. reqFtp.KeepAlive = false;
  85. if (ifCredential) //使用用户身份认证
  86. {
  87. ftpsize.Credentials = new NetworkCredential(Username, Password);
  88. reqFtp.Credentials = new NetworkCredential(Username, Password);
  89. }
  90. ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
  91. using var re = (FtpWebResponse)ftpsize.GetResponse();
  92. long totalBytes = re.ContentLength;
  93. reqFtp.Method = WebRequestMethods.Ftp.DownloadFile;
  94. using var response = (FtpWebResponse)reqFtp.GetResponse();
  95. using var ftpStream = response.GetResponseStream();
  96. //更新进度
  97. updateProgress?.Invoke((int)totalBytes, 0); //更新进度条
  98. long totalDownloadedByte = 0;
  99. int bufferSize = 1024 * 1024;
  100. byte[] buffer = new byte[bufferSize];
  101. if (ftpStream != null)
  102. {
  103. var readCount = ftpStream.Read(buffer, 0, bufferSize);
  104. while (readCount > 0)
  105. {
  106. totalDownloadedByte = readCount + totalDownloadedByte;
  107. outputStream.Write(buffer, 0, readCount);
  108. //更新进度
  109. updateProgress?.Invoke((int)totalBytes, (int)totalDownloadedByte); //更新进度条
  110. readCount = ftpStream.Read(buffer, 0, bufferSize);
  111. }
  112. }
  113. }
  114. /// <summary>
  115. /// 从FTP服务器下载文件,指定本地路径和本地文件名(支持断点下载)
  116. /// </summary>
  117. /// <param name="remoteFileName">远程文件名</param>
  118. /// <param name="localFileName">保存本地的文件名(包含路径)</param>
  119. /// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
  120. /// <param name="size">已下载文件流大小</param>
  121. /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
  122. public void BrokenDownload(string remoteFileName, string localFileName, bool ifCredential, long size, Action<int, int> updateProgress = null)
  123. {
  124. using var outputStream = new FileStream(localFileName, FileMode.Append);
  125. if (FtpServer == null || FtpServer.Trim().Length == 0)
  126. {
  127. throw new Exception("ftp下载目标服务器地址未设置!");
  128. }
  129. Uri uri = new Uri("ftp://" + FtpServer + "/" + remoteFileName);
  130. var ftpsize = (FtpWebRequest)WebRequest.Create(uri);
  131. ftpsize.UseBinary = true;
  132. ftpsize.ContentOffset = size;
  133. var reqFtp = (FtpWebRequest)WebRequest.Create(uri);
  134. reqFtp.UseBinary = true;
  135. reqFtp.KeepAlive = false;
  136. reqFtp.ContentOffset = size;
  137. if (ifCredential) //使用用户身份认证
  138. {
  139. ftpsize.Credentials = new NetworkCredential(Username, Password);
  140. reqFtp.Credentials = new NetworkCredential(Username, Password);
  141. }
  142. ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
  143. using var re = (FtpWebResponse)ftpsize.GetResponse();
  144. var totalBytes = re.ContentLength;
  145. reqFtp.Method = WebRequestMethods.Ftp.DownloadFile;
  146. using var response = (FtpWebResponse)reqFtp.GetResponse();
  147. using var ftpStream = response.GetResponseStream();
  148. updateProgress?.Invoke((int)totalBytes, 0); //更新进度条
  149. long totalDownloadedByte = 0;
  150. int bufferSize = 1024 * 1024;
  151. byte[] buffer = new byte[bufferSize];
  152. if (ftpStream != null)
  153. {
  154. var readCount = ftpStream.Read(buffer, 0, bufferSize);
  155. while (readCount > 0)
  156. {
  157. totalDownloadedByte = readCount + totalDownloadedByte;
  158. outputStream.Write(buffer, 0, readCount);
  159. //更新进度
  160. updateProgress?.Invoke((int)totalBytes, (int)totalDownloadedByte); //更新进度条
  161. readCount = ftpStream.Read(buffer, 0, bufferSize);
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// 从FTP服务器下载文件,指定本地路径和本地文件名
  167. /// </summary>
  168. /// <param name="remoteFileName">远程文件名</param>
  169. /// <param name="localFileName">保存本地的文件名(包含路径)</param>
  170. /// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
  171. /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
  172. /// <param name="brokenOpen">是否断点下载:true 会在localFileName 找是否存在已经下载的文件,并计算文件流大小</param>
  173. public void Download(string remoteFileName, string localFileName, bool ifCredential, bool brokenOpen, Action<int, int> updateProgress = null)
  174. {
  175. if (brokenOpen)
  176. {
  177. long size = 0;
  178. if (File.Exists(localFileName))
  179. {
  180. using var outputStream = new FileStream(localFileName, FileMode.Open);
  181. size = outputStream.Length;
  182. }
  183. BrokenDownload(remoteFileName, localFileName, ifCredential, size, updateProgress);
  184. }
  185. Download(remoteFileName, localFileName, ifCredential, updateProgress);
  186. }
  187. #endregion
  188. #region 上传文件到FTP服务器
  189. /// <summary>
  190. /// 上传文件到FTP服务器
  191. /// </summary>
  192. /// <param name="relativePath">相对目录</param>
  193. /// <param name="localFullPathName">本地带有完整路径的文件名</param>
  194. /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
  195. public void UploadFile(string relativePath, string localFullPathName, Action<int, int> updateProgress = null)
  196. {
  197. var finfo = new FileInfo(localFullPathName);
  198. if (FtpServer == null || FtpServer.Trim().Length == 0)
  199. {
  200. throw new Exception("ftp上传目标服务器地址未设置!");
  201. }
  202. Uri uri = new Uri("ftp://" + FtpServer + "/" + relativePath + "/" + finfo.Name);
  203. var reqFtp = (FtpWebRequest)WebRequest.Create(uri);
  204. reqFtp.KeepAlive = false;
  205. reqFtp.UseBinary = true;
  206. reqFtp.Credentials = new NetworkCredential(Username, Password); //用户,密码
  207. reqFtp.Method = WebRequestMethods.Ftp.UploadFile; //向服务器发出下载请求命令
  208. reqFtp.ContentLength = finfo.Length; //为request指定上传文件的大小
  209. int buffLength = 1024 * 1024;
  210. byte[] buff = new byte[buffLength];
  211. using var fs = finfo.OpenRead();
  212. using var stream = reqFtp.GetRequestStream();
  213. var contentLen = fs.Read(buff, 0, buffLength);
  214. int allbye = (int)finfo.Length;
  215. //更新进度
  216. updateProgress?.Invoke(allbye, 0); //更新进度条
  217. int startbye = 0;
  218. while (contentLen != 0)
  219. {
  220. startbye = contentLen + startbye;
  221. stream.Write(buff, 0, contentLen);
  222. //更新进度
  223. updateProgress?.Invoke(allbye, startbye); //更新进度条
  224. contentLen = fs.Read(buff, 0, buffLength);
  225. }
  226. }
  227. /// <summary>
  228. /// 上传文件到FTP服务器(断点续传)
  229. /// </summary>
  230. /// <param name="localFullPath">本地文件全路径名称:C:\Users\JianKunKing\Desktop\IronPython脚本测试工具</param>
  231. /// <param name="remoteFilepath">远程文件所在文件夹路径</param>
  232. /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
  233. /// <returns></returns>
  234. public bool UploadBroken(string localFullPath, string remoteFilepath, Action<int, int> updateProgress = null)
  235. {
  236. if (remoteFilepath == null)
  237. {
  238. remoteFilepath = "";
  239. }
  240. string newFileName;
  241. var fileInf = new FileInfo(localFullPath);
  242. long allbye = fileInf.Length;
  243. if (fileInf.Name.IndexOf("#", StringComparison.Ordinal) == -1)
  244. {
  245. newFileName = RemoveSpaces(fileInf.Name);
  246. }
  247. else
  248. {
  249. newFileName = fileInf.Name.Replace("#", "#");
  250. newFileName = RemoveSpaces(newFileName);
  251. }
  252. long startfilesize = GetFileSize(newFileName, remoteFilepath);
  253. if (startfilesize >= allbye)
  254. {
  255. return false;
  256. }
  257. long startbye = startfilesize;
  258. //更新进度
  259. updateProgress?.Invoke((int)allbye, (int)startfilesize); //更新进度条
  260. string uri;
  261. if (remoteFilepath.Length == 0)
  262. {
  263. uri = "ftp://" + FtpServer + "/" + newFileName;
  264. }
  265. else
  266. {
  267. uri = "ftp://" + FtpServer + "/" + remoteFilepath + "/" + newFileName;
  268. }
  269. // 根据uri创建FtpWebRequest对象
  270. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(uri));
  271. // ftp用户名和密码
  272. reqFtp.Credentials = new NetworkCredential(Username, Password);
  273. // 默认为true,连接不会被关闭
  274. // 在一个命令之后被执行
  275. reqFtp.KeepAlive = false;
  276. // 指定执行什么命令
  277. reqFtp.Method = WebRequestMethods.Ftp.AppendFile;
  278. // 指定数据传输类型
  279. reqFtp.UseBinary = true;
  280. // 上传文件时通知服务器文件的大小
  281. reqFtp.ContentLength = fileInf.Length;
  282. int buffLength = 1024 * 1024; // 缓冲大小设置为2kb
  283. byte[] buff = new byte[buffLength];
  284. // 打开一个文件流 (System.IO.FileStream) 去读上传的文件
  285. using FileStream fs = fileInf.OpenRead();
  286. using var strm = reqFtp.GetRequestStream();
  287. // 把上传的文件写入流
  288. fs.Seek(startfilesize, 0);
  289. int contentLen = fs.Read(buff, 0, buffLength);
  290. // 流内容没有结束
  291. while (contentLen != 0)
  292. {
  293. // 把内容从file stream 写入 upload stream
  294. strm.Write(buff, 0, contentLen);
  295. contentLen = fs.Read(buff, 0, buffLength);
  296. startbye += contentLen;
  297. //更新进度
  298. updateProgress?.Invoke((int)allbye, (int)startbye); //更新进度条
  299. }
  300. return true;
  301. }
  302. /// <summary>
  303. /// 去除空格
  304. /// </summary>
  305. /// <param name="str"></param>
  306. /// <returns></returns>
  307. private string RemoveSpaces(string str)
  308. {
  309. string a = str.Where(c => Encoding.ASCII.GetBytes(c.ToString())[0] != 32).Aggregate("", (current, c) => current + c);
  310. return a.Split('.')[a.Split('.').Length - 2] + "." + a.Split('.')[a.Split('.').Length - 1];
  311. }
  312. /// <summary>
  313. /// 获取已上传文件大小
  314. /// </summary>
  315. /// <param name="filePath">文件名称</param>
  316. /// <param name="remoteFilepath">服务器文件路径</param>
  317. /// <returns></returns>
  318. public long GetFileSize(string filePath, string remoteFilepath)
  319. {
  320. try
  321. {
  322. var fi = new FileInfo(filePath);
  323. string uri;
  324. if (remoteFilepath.Length == 0)
  325. {
  326. uri = "ftp://" + FtpServer + "/" + fi.Name;
  327. }
  328. else
  329. {
  330. uri = "ftp://" + FtpServer + "/" + remoteFilepath + "/" + fi.Name;
  331. }
  332. var reqFtp = (FtpWebRequest)WebRequest.Create(uri);
  333. reqFtp.KeepAlive = false;
  334. reqFtp.UseBinary = true;
  335. reqFtp.Credentials = new NetworkCredential(Username, Password); //用户,密码
  336. reqFtp.Method = WebRequestMethods.Ftp.GetFileSize;
  337. var response = (FtpWebResponse)reqFtp.GetResponse();
  338. var filesize = response.ContentLength;
  339. return filesize;
  340. }
  341. catch
  342. {
  343. return 0;
  344. }
  345. }
  346. #endregion
  347. #region 获取当前目录下明细
  348. /// <summary>
  349. /// 获取当前目录下明细(包含文件和文件夹)
  350. /// </summary>
  351. /// <returns></returns>
  352. public List<string> GetFilesDetails(string relativePath = "")
  353. {
  354. var result = new List<string>();
  355. var ftp = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine("ftp://" + FtpServer, relativePath).Replace("\\", "/")));
  356. ftp.Credentials = new NetworkCredential(Username, Password);
  357. ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
  358. using var response = ftp.GetResponse();
  359. using var reader = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
  360. string line = reader.ReadLine();
  361. while (line != null)
  362. {
  363. result.Add(line);
  364. line = reader.ReadLine();
  365. }
  366. return result;
  367. }
  368. /// <summary>
  369. /// 获取当前目录下文件列表(仅文件)
  370. /// </summary>
  371. /// <returns></returns>
  372. public List<string> GetFiles(string relativePath = "", string mask = "*.*")
  373. {
  374. var result = new List<string>();
  375. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine("ftp://" + FtpServer, relativePath).Replace("\\", "/")));
  376. reqFtp.UseBinary = true;
  377. reqFtp.Credentials = new NetworkCredential(Username, Password);
  378. reqFtp.Method = WebRequestMethods.Ftp.ListDirectory;
  379. using var response = reqFtp.GetResponse();
  380. using var reader = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
  381. string line = reader.ReadLine();
  382. while (line != null)
  383. {
  384. if (mask.Trim() != string.Empty && mask.Trim() != "*.*")
  385. {
  386. string temp = mask.Substring(0, mask.IndexOf("*", StringComparison.Ordinal));
  387. if (line.Substring(0, temp.Length) == temp)
  388. {
  389. result.Add(line);
  390. }
  391. }
  392. else
  393. {
  394. result.Add(line);
  395. }
  396. line = reader.ReadLine();
  397. }
  398. return result;
  399. }
  400. /// <summary>
  401. /// 获取当前目录下所有的文件夹列表(仅文件夹)
  402. /// </summary>
  403. /// <returns></returns>
  404. public string[] GetDirectories(string relativePath)
  405. {
  406. var drectory = GetFilesDetails(relativePath);
  407. string m = string.Empty;
  408. foreach (string str in drectory)
  409. {
  410. int dirPos = str.IndexOf("<DIR>", StringComparison.Ordinal);
  411. if (dirPos > 0)
  412. {
  413. /*判断 Windows 风格*/
  414. m += str.Substring(dirPos + 5).Trim() + "\n";
  415. }
  416. else if (str.Trim().StartsWith("d"))
  417. {
  418. /*判断 Unix 风格*/
  419. string dir = str.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)[8];
  420. if (dir != "." && dir != "..")
  421. {
  422. dir = str.Substring(str.IndexOf(dir, StringComparison.Ordinal));
  423. m += dir + "\n";
  424. }
  425. }
  426. }
  427. char[] n =
  428. {
  429. '\n'
  430. };
  431. return m.Split(n);
  432. }
  433. #endregion
  434. #region 删除文件及文件夹
  435. /// <summary>
  436. /// 删除文件
  437. /// </summary>
  438. /// <param name="filePath"></param>
  439. public void Delete(string filePath)
  440. {
  441. string uri = Path.Combine("ftp://" + FtpServer, filePath).Replace("\\", "/");
  442. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(uri));
  443. reqFtp.Credentials = new NetworkCredential(Username, Password);
  444. reqFtp.KeepAlive = false;
  445. reqFtp.Method = WebRequestMethods.Ftp.DeleteFile;
  446. using FtpWebResponse response = (FtpWebResponse)reqFtp.GetResponse();
  447. using Stream datastream = response.GetResponseStream();
  448. using StreamReader sr = new StreamReader(datastream ?? throw new InvalidOperationException());
  449. sr.ReadToEnd();
  450. }
  451. /// <summary>
  452. /// 删除文件夹
  453. /// </summary>
  454. /// <param name="dirPath"></param>
  455. public void RemoveDirectory(string dirPath)
  456. {
  457. string uri = Path.Combine("ftp://" + FtpServer, dirPath).Replace("\\", "/");
  458. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(uri));
  459. reqFtp.Credentials = new NetworkCredential(Username, Password);
  460. reqFtp.KeepAlive = false;
  461. reqFtp.Method = WebRequestMethods.Ftp.RemoveDirectory;
  462. using var response = (FtpWebResponse)reqFtp.GetResponse();
  463. using var datastream = response.GetResponseStream();
  464. using var sr = new StreamReader(datastream ?? throw new InvalidOperationException());
  465. sr.ReadToEnd();
  466. }
  467. #endregion
  468. #region 其他操作
  469. /// <summary>
  470. /// 获取指定文件大小
  471. /// </summary>
  472. /// <param name="filePath"></param>
  473. /// <returns></returns>
  474. public long GetFileSize(string filePath)
  475. {
  476. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine("ftp://" + FtpServer, filePath).Replace("\\", "/")));
  477. reqFtp.Method = WebRequestMethods.Ftp.GetFileSize;
  478. reqFtp.UseBinary = true;
  479. reqFtp.Credentials = new NetworkCredential(Username, Password);
  480. using var response = (FtpWebResponse)reqFtp.GetResponse();
  481. var fileSize = response.ContentLength;
  482. return fileSize;
  483. }
  484. /// <summary>
  485. /// 判断当前目录下指定的子目录是否存在
  486. /// </summary>
  487. /// <param name="remoteDirPath">指定的目录名</param>
  488. public bool DirectoryExist(string remoteDirPath)
  489. {
  490. try
  491. {
  492. string[] dirList = GetDirectories(remoteDirPath);
  493. return dirList.Any(str => str.Trim() == remoteDirPath.Trim());
  494. }
  495. catch
  496. {
  497. return false;
  498. }
  499. }
  500. /// <summary>
  501. /// 判断当前目录下指定的文件是否存在
  502. /// </summary>
  503. /// <param name="remoteFileName">远程文件名</param>
  504. public bool FileExist(string remoteFileName)
  505. {
  506. return GetFiles("*.*").Any(str => str.Trim() == remoteFileName.Trim());
  507. }
  508. /// <summary>
  509. /// 创建文件夹
  510. /// </summary>
  511. /// <param name="relativePath">路径</param>
  512. /// <param name="newDir">新建文件夹</param>
  513. public void MakeDir(string relativePath, string newDir)
  514. {
  515. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine("ftp://" + FtpServer, relativePath, newDir).Replace("\\", "/")));
  516. reqFtp.Method = WebRequestMethods.Ftp.MakeDirectory;
  517. reqFtp.UseBinary = true;
  518. reqFtp.Credentials = new NetworkCredential(Username, Password);
  519. using var response = (FtpWebResponse)reqFtp.GetResponse();
  520. using var _ = response.GetResponseStream();
  521. }
  522. /// <summary>
  523. /// 改名
  524. /// </summary>
  525. /// <param name="relativePath">相对路径</param>
  526. /// <param name="currentFilename"></param>
  527. /// <param name="newFilename"></param>
  528. public void Rename(string relativePath, string currentFilename, string newFilename)
  529. {
  530. var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine("ftp://" + FtpServer, relativePath, currentFilename).Replace("\\", "/")));
  531. reqFtp.Method = WebRequestMethods.Ftp.Rename;
  532. reqFtp.RenameTo = newFilename;
  533. reqFtp.UseBinary = true;
  534. reqFtp.Credentials = new NetworkCredential(Username, Password);
  535. using var response = (FtpWebResponse)reqFtp.GetResponse();
  536. using var _ = response.GetResponseStream();
  537. }
  538. /// <summary>
  539. /// 移动文件
  540. /// </summary>
  541. /// <param name="relativePath">相对路径</param>
  542. /// <param name="currentFilename"></param>
  543. /// <param name="newDirectory"></param>
  544. public void MoveFile(string relativePath, string currentFilename, string newDirectory)
  545. {
  546. Rename(relativePath, currentFilename, newDirectory);
  547. }
  548. #endregion
  549. }
  550. }