1.整理簡化了下C#的ftp操作,友善使用
1.支援建立多級目錄
2.批量删除
3.整個目錄上傳
4.整個目錄删除
5.整個目錄下載下傳
2.調用方法展示,
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");//建立多級目錄
3.FtpHelper 代碼。
1.異常方法委托,通過Lamda委托統一處理異常,友善改寫。加了個委托友善控制異常輸出
2.ftp的删除需要遞歸查找所有目錄存入list,然後根據 level倒序排序,從最末級開始周遊删除
3.其他的整個目錄操作都是同上
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 }