C#开发--FTP操作方法管理

时间:2023-03-09 14:45:54
C#开发--FTP操作方法管理

1.整理简化了下C#的ftp操作,方便使用

   1.支持创建多级目录

   2.批量删除

   3.整个目录上传

   4.整个目录删除

   5.整个目录下载

2.调用方法展示,

C#开发--FTP操作方法管理
C#开发--FTP操作方法管理
            var ftp = new FtpHelper("10.136.12.11", "qdx1213123", "123ddddf");//初始化ftp,创建ftp对象
ftp.DelAll("test");//删除ftptest目录及其目录下的所有文件
ftp.UploadAllFile("F:\\test\\wms.zip");//上传单个文件到指定目录
ftp.UploadAllFile("F:\\test");//将本地test目录的所有文件上传
ftp.DownloadFile("test\\wms.zip", "F:\\test1");//下载单个目录
ftp.DownloadAllFile("test", "F:\\test1");//批量下载整个目录
ftp.MakeDir("aaa\\bbb\\ccc\\ddd");//创建多级目录
C#开发--FTP操作方法管理
C#开发--FTP操作方法管理

3.FtpHelper 代码。

1.异常方法委托,通过Lamda委托统一处理异常,方便改写。加了个委托方便控制异常输出

2.ftp的删除需要递归查找所有目录存入list,然后根据 level倒序排序,从最末级开始遍历删除

3.其他的整个目录操作都是同上

C#开发--FTP操作方法管理
  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.IO;
6
7 namespace MyStuday
8 {
9 /// <summary>
10 /// ftp帮助类
11 /// </summary>
12 public class FtpHelper
13 {
14 private string ftpHostIP { get; set; }
15 private string username { get; set; }
16 private string password { get; set; }
17 private string ftpURI { get { return $@"ftp://{ftpHostIP}/"; } }
18
19 /// <summary>
20 /// 初始化ftp参数
21 /// </summary>
22 /// <param name="ftpHostIP">ftp主机IP</param>
23 /// <param name="username">ftp账户</param>
24 /// <param name="password">ftp密码</param>
25 public FtpHelper(string ftpHostIP, string username, string password)
26 {
27 this.ftpHostIP = ftpHostIP;
28 this.username = username;
29 this.password = password;
30 }
31
32 /// <summary>
33 /// 异常方法委托,通过Lamda委托统一处理异常,方便改写
34 /// </summary>
35 /// <param name="method">当前执行的方法</param>
36 /// <param name="action"></param>
37 /// <returns></returns>
38 private bool MethodInvoke(string method, Action action)
39 {
40 if (action != null)
41 {
42 try
43 {
44 action();
45 //Logger.Write2File($@"FtpHelper.{method}:执行成功");
46 FluentConsole.Magenta.Line($@"FtpHelper({ftpHostIP},{username},{password}).{method}:执行成功");
47 return true;
48 }
49 catch (Exception ex)
50 {
51 FluentConsole.Red.Line($@"FtpHelper({ftpHostIP},{username},{password}).{method}:执行失败:\n {ex}");
52 // Logger.Write2File(FtpHelper({ftpHostIP},{username},{password}).{method}:执行失败 \r\n{ex}");
53 return false;
54 }
55 }
56 else
57 {
58 return false;
59 }
60 }
61
62 /// <summary>
63 /// 异常方法委托,通过Lamda委托统一处理异常,方便改写
64 /// </summary>
65 /// </summary>
66 /// <typeparam name="T"></typeparam>
67 /// <param name="method"></param>
68 /// <param name="func"></param>
69 /// <returns></returns>
70 private T MethodInvoke<T>(string method, Func<T> func)
71 {
72 if (func != null)
73 {
74 try
75 {
76 //FluentConsole.Magenta.Line($@"FtpHelper({ftpHostIP},{username},{password}).{method}:执行成功");
77 //Logger.Write2File($@"FtpHelper({ftpHostIP},{username},{password}).{method}:执行成功");
78 return func();
79 }
80 catch (Exception ex)
81 {
82 //FluentConsole.Red.Line($@"FtpHelper({ftpHostIP},{username},{password}).{method}:执行失败:").Line(ex);
83 // Logger.Write2File($@"FtpHelper({ftpHostIP},{username},{password}).{method}:执行失败 \r\n{ex}");
84 return default(T);
85 }
86 }
87 else
88 {
89 return default(T);
90 }
91 }
92 private FtpWebRequest GetRequest(string URI)
93 {
94 //根据服务器信息FtpWebRequest创建类的对象
95 FtpWebRequest result = (FtpWebRequest)WebRequest.Create(URI);
96 result.Credentials = new NetworkCredential(username, password);
97 result.KeepAlive = false;
98 result.UsePassive = false;
99 result.UseBinary = true;
100 return result;
101 }
102
103 /// <summary> 上传文件</summary>
104 /// <param name="filePath">需要上传的文件路径</param>
105 /// <param name="dirName">目标路径</param>
106 public bool UploadFile(string filePath, string dirName = "")
107 {
108 FileInfo fileInfo = new FileInfo(filePath);
109 if (dirName != "") MakeDir(dirName);//检查文件目录,不存在就自动创建
110 string uri = Path.Combine(ftpURI, dirName, fileInfo.Name);
111 return MethodInvoke($@"uploadFile({filePath},{dirName})", () =>
112 {
113 FtpWebRequest ftp = GetRequest(uri);
114 ftp.Method = WebRequestMethods.Ftp.UploadFile;
115 ftp.ContentLength = fileInfo.Length;
116 int buffLength = 2048;
117 byte[] buff = new byte[buffLength];
118 int contentLen;
119 using (FileStream fs = fileInfo.OpenRead())
120 {
121 using (Stream strm = ftp.GetRequestStream())
122 {
123 contentLen = fs.Read(buff, 0, buffLength);
124 while (contentLen != 0)
125 {
126 strm.Write(buff, 0, contentLen);
127 contentLen = fs.Read(buff, 0, buffLength);
128 }
129 strm.Close();
130 }
131 fs.Close();
132 }
133 });
134 }
135
136 /// <summary>
137 /// 从一个目录将其内容复制到另一目录
138 /// </summary>
139 /// <param name="localDir">源目录</param>
140 /// <param name="DirName">目标目录</param>
141 public void UploadAllFile(string localDir, string DirName = "")
142 {
143 string localDirName = string.Empty;
144 int targIndex = localDir.LastIndexOf("\\");
145 if (targIndex > -1 && targIndex != (localDir.IndexOf(":\\") + 1))
146 localDirName = localDir.Substring(0, targIndex);
147 localDirName = localDir.Substring(targIndex + 1);
148 string newDir = Path.Combine(DirName, localDirName);
149 MethodInvoke($@"UploadAllFile({localDir},{DirName})", () =>
150 {
151 MakeDir(newDir);
152 DirectoryInfo directoryInfo = new DirectoryInfo(localDir);
153 FileInfo[] files = directoryInfo.GetFiles();
154 //复制所有文件
155 foreach (FileInfo file in files)
156 {
157 UploadFile(file.FullName, newDir);
158 }
159 //最后复制目录
160 DirectoryInfo[] directoryInfoArray = directoryInfo.GetDirectories();
161 foreach (DirectoryInfo dir in directoryInfoArray)
162 {
163 UploadAllFile(Path.Combine(localDir, dir.Name), newDir);
164 }
165 });
166 }
167
168 /// <summary>
169 /// 删除单个文件
170 /// </summary>
171 /// <param name="filePath"></param>
172 public bool DelFile(string filePath)
173 {
174 string uri = Path.Combine(ftpURI, filePath);
175 return MethodInvoke($@"DelFile({filePath})", () =>
176 {
177 FtpWebRequest ftp = GetRequest(uri);
178 ftp.Method = WebRequestMethods.Ftp.DeleteFile;
179 FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
180 response.Close();
181 });
182 }
183
184 /// <summary>
185 /// 删除最末及空目录
186 /// </summary>
187 /// <param name="dirName"></param>
188 private bool DelDir(string dirName)
189 {
190 string uri = Path.Combine(ftpURI, dirName);
191 return MethodInvoke($@"DelDir({dirName})", () =>
192 {
193 FtpWebRequest ftp = GetRequest(uri);
194 ftp.Method = WebRequestMethods.Ftp.RemoveDirectory;
195 FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
196 response.Close();
197 });
198 }
199
200 /// <summary> 删除目录或者其目录下所有的文件 </summary>
201 /// <param name="dirName">目录名称</param>
202 /// <param name="ifDelSub">是否删除目录下所有的文件</param>
203 public bool DelAll(string dirName)
204 {
205 var list = GetAllFtpFile(new List<ActFile>(),dirName);
206 if (list == null) return DelDir(dirName);
207 if (list.Count==0) return DelDir(dirName);//删除当前目录
208 var newlist = list.OrderByDescending(x => x.level);
209 foreach (var item in newlist)
210 {
211 FluentConsole.Yellow.Line($@"level:{item.level},isDir:{item.isDir},path:{item.path}");
212 }
213 string uri = Path.Combine(ftpURI, dirName);
214 return MethodInvoke($@"DelAll({dirName})", () =>
215 {
216 foreach (var item in newlist)
217 {
218 if (item.isDir)//判断是目录调用目录的删除方法
219 DelDir(item.path);
220 else
221 DelFile(item.path);
222 }
223 DelDir(dirName);//删除当前目录
224 return true;
225 });
226 }
227
228 /// <summary>
229 /// 下载单个文件
230 /// </summary>
231 /// <param name="ftpFilePath">从ftp要下载的文件路径</param>
232 /// <param name="localDir">下载至本地路径</param>
233 /// <param name="filename">文件名</param>
234 public bool DownloadFile(string ftpFilePath, string saveDir)
235 {
236 string filename = ftpFilePath.Substring(ftpFilePath.LastIndexOf("\\") + 1);
237 string tmpname = Guid.NewGuid().ToString();
238 string uri = Path.Combine(ftpURI, ftpFilePath);
239 return MethodInvoke($@"DownloadFile({ftpFilePath},{saveDir},{filename})", () =>
240 {
241 if (!Directory.Exists(saveDir)) Directory.CreateDirectory(saveDir);
242 FtpWebRequest ftp = GetRequest(uri);
243 ftp.Method = WebRequestMethods.Ftp.DownloadFile;
244 using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
245 {
246 using (Stream responseStream = response.GetResponseStream())
247 {
248 using (FileStream fs = new FileStream(Path.Combine(saveDir, filename), FileMode.CreateNew))
249 {
250 byte[] buffer = new byte[2048];
251 int read = 0;
252 do
253 {
254 read = responseStream.Read(buffer, 0, buffer.Length);
255 fs.Write(buffer, 0, read);
256 } while (!(read == 0));
257 responseStream.Close();
258 fs.Flush();
259 fs.Close();
260 }
261 responseStream.Close();
262 }
263 response.Close();
264 }
265 });
266 }
267
268 /// <summary>
269 /// 从FTP下载整个文件夹
270 /// </summary>
271 /// <param name="dirName">FTP文件夹路径</param>
272 /// <param name="saveDir">保存的本地文件夹路径</param>
273 public void DownloadAllFile(string dirName, string saveDir)
274 {
275 MethodInvoke($@"DownloadAllFile({dirName},{saveDir})", () =>
276 {
277 List<ActFile> files = GetFtpFile(dirName);
278 if (!Directory.Exists(saveDir))
279 {
280 Directory.CreateDirectory(saveDir);
281 }
282 foreach (var f in files)
283 {
284 if (f.isDir) //文件夹,递归查询
285 {
286 DownloadAllFile(Path.Combine(dirName,f.name), Path.Combine(saveDir ,f.name));
287 }
288 else //文件,直接下载
289 {
290 DownloadFile(Path.Combine(dirName,f.name), saveDir);
291 }
292 }
293 });
294 }
295
296 /// <summary>
297 /// 获取当前目录下的目录及文件
298 /// </summary>
299 /// param name="ftpfileList"></param>
300 /// <param name="dirName"></param>
301 /// <returns></returns>
302 public List<ActFile> GetFtpFile(string dirName,int ilevel = 0)
303 {
304 var ftpfileList = new List<ActFile>();
305 string uri = Path.Combine(ftpURI, dirName);
306 return MethodInvoke($@"GetFtpFile({dirName})", () =>
307 {
308 var a = new List<List<string>>();
309 FtpWebRequest ftp = GetRequest(uri);
310 ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
311 Stream stream = ftp.GetResponse().GetResponseStream();
312 using (StreamReader sr = new StreamReader(stream))
313 {
314 string line = sr.ReadLine();
315 while (!string.IsNullOrEmpty(line))
316 {
317 ftpfileList.Add(new ActFile { isDir = line.IndexOf("<DIR>") > -1, name = line.Substring(39).Trim(), path = Path.Combine(dirName, line.Substring(39).Trim()), level= ilevel });
318 line = sr.ReadLine();
319 }
320 sr.Close();
321 }
322 return ftpfileList;
323 });
324
325
326 }
327
328 /// <summary>
329 /// 获取FTP目录下的所有目录及文件包括其子目录和子文件
330 /// </summary>
331 /// param name="result"></param>
332 /// <param name="dirName"></param>
333 /// <returns></returns>
334 public List<ActFile> GetAllFtpFile(List<ActFile> result,string dirName, int level = 0)
335 {
336 var ftpfileList = new List<ActFile>();
337 string uri = Path.Combine(ftpURI, dirName);
338 return MethodInvoke($@"GetAllFtpFile({dirName})", () =>
339 {
340 ftpfileList = GetFtpFile(dirName, level);
341 result.AddRange(ftpfileList);
342 var newlist = ftpfileList.Where(x => x.isDir).ToList();
343 foreach (var item in newlist)
344 {
345 GetAllFtpFile(result,item.path, level+1);
346 }
347 return result;
348 });
349
350 }
351
352 /// <summary>
353 /// 检查目录是否存在
354 /// </summary>
355 /// <param name="dirName"></param>
356 /// <param name="currentDir"></param>
357 /// <returns></returns>
358 public bool CheckDir(string dirName, string currentDir = "")
359 {
360 string uri = Path.Combine(ftpURI, currentDir);
361 return MethodInvoke($@"CheckDir({dirName}{currentDir})", () =>
362 {
363 FtpWebRequest ftp = GetRequest(uri);
364 ftp.UseBinary = true;
365 ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
366 Stream stream = ftp.GetResponse().GetResponseStream();
367 using (StreamReader sr = new StreamReader(stream))
368 {
369 string line = sr.ReadLine();
370 while (!string.IsNullOrEmpty(line))
371 {
372 if (line.IndexOf("<DIR>") > -1)
373 {
374 if (line.Substring(39).Trim() == dirName)
375 return true;
376 }
377 line = sr.ReadLine();
378 }
379 sr.Close();
380 }
381 stream.Close();
382 return false;
383 });
384
385 }
386
387 /// </summary>
388 /// 在ftp服务器上创建指定目录,父目录不存在则创建
389 /// </summary>
390 /// <param name="dirName">创建的目录名称</param>
391 public bool MakeDir(string dirName)
392 {
393 var dirs = dirName.Split('\\').ToList();//针对多级目录分割
394 string currentDir = string.Empty;
395 return MethodInvoke($@"MakeDir({dirName})", () =>
396 {
397 foreach (var dir in dirs)
398 {
399 if (!CheckDir(dir, currentDir))//检查目录不存在则创建
400 {
401 currentDir = Path.Combine(currentDir, dir);
402 string uri = Path.Combine(ftpURI, currentDir);
403 FtpWebRequest ftp = GetRequest(uri);
404 ftp.Method = WebRequestMethods.Ftp.MakeDirectory;
405 FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
406 response.Close();
407 }
408 else
409 {
410 currentDir = Path.Combine(currentDir, dir);
411 }
412 }
413
414 });
415
416 }
417
418 /// <summary>文件重命名 </summary>
419 /// <param name="currentFilename">当前名称</param>
420 /// <param name="newFilename">重命名名称</param>
421 /// <param name="currentFilename">所在的目录</param>
422 public bool Rename(string currentFilename, string newFilename, string dirName = "")
423 {
424 string uri = Path.Combine(ftpURI, dirName, currentFilename);
425 return MethodInvoke($@"Rename({currentFilename},{newFilename},{dirName})", () =>
426 {
427 FtpWebRequest ftp = GetRequest(uri);
428 ftp.Method = WebRequestMethods.Ftp.Rename;
429 ftp.RenameTo = newFilename;
430 FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
431 response.Close();
432 });
433 }
434 }
435
436 public class ActFile
437 {
438 public int level { get; set; } = 0;
439 public bool isDir { get; set; }
440 public string name { get; set; }
441 public string path { get; set; } = "";
442 }
443 }