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.Text.RegularExpressions; 8 9 namespace Common 10 { 11 /// <summary> 12 /// FTP类 13 /// </summary> 14 public class FTP 15 { 16 private string _ftpServerIP; 17 private string _ftpUserName; 18 private string _ftpPassword; 19 private Uri ftpUri; 20 private string _path; 21 22 /// <summary> 23 /// 24 /// </summary> 25 /// <param name="ftpServerIp">ip:port,默认21端口可以只写ip</param> 26 /// <param name="username"></param> 27 /// <param name="passwd"></param> 28 public FTP(string ftpServerIp, string username, string passwd) 29 { 30 _ftpServerIP = ftpServerIp; 31 _ftpUserName = username; 32 _ftpPassword = passwd; 33 this.ftpUri = new Uri("ftp://" + ftpServerIp); 34 } 35 36 /// <summary> 37 /// 38 /// </summary> 39 /// <param name="ftpServerIp">ip:port,默认21端口可以只写ip</param> 40 /// <param name="username"></param> 41 /// <param name="passwd"></param> 42 /// <param name="ftp_path"></param> 43 public FTP(string ftpServerIp, string username, string passwd, string ftp_path) : this(ftpServerIp, username, passwd) 44 { 45 _path = ftp_path; 46 this.ftpUri = new Uri("ftp://" + ftpServerIp + "/" + ftp_path); 47 } 48 49 /// <summary> 50 /// 获取文件及文件夹列表 51 /// </summary> 52 /// <returns></returns> 53 public List<FileStruct> GetList() 54 { 55 string dataString = GetFiles(); 56 DirectoryListParser parser = new DirectoryListParser(dataString); 57 return parser.MyListArray; 58 } 59 60 /// <summary> 61 /// 获得当前文件夹下的所有文件夹 62 /// </summary> 63 /// <returns></returns> 64 public List<string> GetAllFolder() 65 { 66 string dataString = GetFiles(); 67 DirectoryListParser parser = new DirectoryListParser(dataString); 68 List<string> result = new List<string>(); 69 parser.DirectoryList.ForEach(x => result.Add(x.Name)); 70 return result; 71 } 72 73 /// <summary> 74 /// 获得当前文件夹下的所有文件 75 /// </summary> 76 /// <returns></returns> 77 public List<string> GetAllFiles() 78 { 79 string dataString = GetFiles(); 80 DirectoryListParser parser = new DirectoryListParser(dataString); 81 List<string> result = new List<string>(); 82 parser.FileList.ForEach(x => result.Add(x.Name)); 83 return result; 84 } 85 86 private string GetFiles() 87 { 88 WebRequest listRequest = WebRequest.Create(ftpUri); 89 listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 90 listRequest.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 91 92 WebResponse listResponse = listRequest.GetResponse(); 93 Stream responseStream = listResponse.GetResponseStream(); 94 StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8); 95 96 string result = ""; 97 if (readStream != null) result = readStream.ReadToEnd(); 98 99 listResponse.Close(); 100 responseStream.Close(); 101 readStream.Close(); 102 return result; 103 } 104 105 /// <summary> 106 /// 创建文件夹 107 /// </summary> 108 /// <param name="dirName">目录,如"aa/cc/bb",只创建bb文件夹</param> 109 public bool MakeDir(string dirName) 110 { 111 try 112 { 113 var reqFTP = WebRequest.Create(new Uri(ftpUri + "/" + dirName)); 114 reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory; 115 reqFTP.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 116 WebResponse response = reqFTP.GetResponse(); 117 Stream ftpStream = response.GetResponseStream(); 118 ftpStream.Close(); 119 response.Close(); 120 return true; 121 } 122 catch (Exception ex) 123 { 124 LogHelper.logger.Error(ex); 125 return false; 126 } 127 } 128 129 /// <summary> 130 /// 上传文件 131 /// </summary> 132 /// <param name="localFile"></param> 133 /// <param name="remoteFileName"></param> 134 /// <returns></returns> 135 public bool Upload(string localFileName, string remoteFileName) 136 { 137 try 138 { 139 string uri = string.Empty; 140 if (this.ftpUri.ToString().EndsWith("/")) uri = this.ftpUri + remoteFileName; 141 else uri = this.ftpUri + "/" + remoteFileName; 142 WebClient myWebClient = new WebClient(); 143 myWebClient.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 144 byte[] responseArray = myWebClient.UploadFile(uri, localFileName); 145 return true; 146 } 147 catch (Exception ex) 148 { 149 LogHelper.logger.Error($"Upload({localFileName},{remoteFileName})", ex); 150 return false; 151 } 152 } 153 154 /// <summary> 155 /// 追加文件内容到远端文件,如果远端文件不存在则上传 156 /// </summary> 157 /// <param name="localFileName">本地文件,如"D:\\aa.txt"</param> 158 /// <param name="remoteFileName">ftp文件,如"A/B/b.txt"</param> 159 public void AppendFile(string localFileName, string remoteFileName) 160 { 161 try 162 { 163 if (!File.Exists(localFileName)) return; 164 FileInfo fileInf = new FileInfo(localFileName); 165 string uri = $"ftp://{_ftpServerIP}/{_path}/{remoteFileName}"; 166 var reqFTP = WebRequest.Create(new Uri(uri)); 167 reqFTP.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 168 reqFTP.Method = WebRequestMethods.Ftp.AppendFile; 169 reqFTP.ContentLength = fileInf.Length; 170 int buffLength = 2048; 171 byte[] buff = new byte[buffLength]; 172 int contentLen; 173 174 using (FileStream fs = fileInf.OpenRead()) 175 using (Stream strm = reqFTP.GetRequestStream()) 176 { 177 contentLen = fs.Read(buff, 0, buffLength); 178 while (contentLen != 0) 179 { 180 strm.Write(buff, 0, contentLen); 181 contentLen = fs.Read(buff, 0, buffLength); 182 } 183 } 184 } 185 catch (Exception ex) 186 { 187 LogHelper.logger.Error(ex); 188 } 189 } 190 191 /// <summary> 192 /// 删除文件 193 /// </summary> 194 /// <param name="fileName">文件名,如“A/B/b.txt”</param> 195 public bool Delete(string fileName) 196 { 197 try 198 { 199 string uri = $"ftp://{_ftpServerIP}/{_path}/{fileName}"; 200 var reqFTP = WebRequest.Create(new Uri(uri)); 201 reqFTP.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 202 reqFTP.Method = WebRequestMethods.Ftp.DeleteFile; 203 string result = String.Empty; 204 using (var response = reqFTP.GetResponse()) 205 using (Stream datastream = response.GetResponseStream()) 206 using (StreamReader sr = new StreamReader(datastream)) 207 { 208 result = sr.ReadToEnd(); 209 } 210 return true; 211 } 212 catch (Exception ex) 213 { 214 LogHelper.logger.Error(ex); 215 return false; 216 } 217 } 218 219 /// <summary> 220 /// 重命名目录 221 /// </summary> 222 /// <param name="currentFilename">原来名称</param> 223 /// <param name="newFilename">新名称</param> 224 public bool ReName(string currentFilename, string newFilename) 225 { 226 FtpWebRequest reqFTP; 227 try 228 { 229 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpUri + currentFilename)); 230 reqFTP.Method = WebRequestMethods.Ftp.Rename; 231 reqFTP.RenameTo = newFilename; 232 reqFTP.UseBinary = true; 233 reqFTP.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 234 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 235 Stream ftpStream = response.GetResponseStream(); 236 ftpStream.Close(); 237 response.Close(); 238 return true; 239 } 240 catch (Exception ex) 241 { 242 LogHelper.logger.Error(ex); 243 return false; 244 } 245 } 246 247 /// <summary> 248 /// 判断目录是否存在 249 /// </summary> 250 /// <param name="path">文件夹所在目录,如:"aa/bb"</param> 251 /// <param name="FolderName">文件夹名称,如:"cc"</param> 252 /// <returns></returns> 253 public bool DirectoryExist(string path, string FolderName) 254 { 255 try 256 { 257 string uri = $"ftp://{_ftpServerIP}/{_path}/{path}"; 258 WebRequest reqFTP = WebRequest.Create(new Uri(uri)); 259 reqFTP.Credentials = new NetworkCredential(this._ftpUserName, this._ftpPassword); 260 reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; 261 262 WebResponse response = reqFTP.GetResponse(); 263 string result = ""; 264 StreamReader readStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8); 265 if (readStream != null) 266 { 267 result = readStream.ReadToEnd(); 268 } 269 response.Close(); 270 271 LogHelper.logger.Debug($"DirectoryExist({path}, {FolderName}) return {result}"); 272 int index = result.IndexOf(FolderName + "\r\n"); 273 return (index == 0 || (index > 0 && result.Substring(index - 1, 1) == "\n")); 274 } 275 catch 276 { 277 return false; 278 } 279 } 280 281 public bool DirectoryExist_ServerU(string path) 282 { 283 string uri = $"ftp://{_ftpServerIP}/{_path}/{path}"; 284 FtpWebRequest reqFtp = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 285 reqFtp.UseBinary = true; 286 reqFtp.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 287 reqFtp.Method = WebRequestMethods.Ftp.ListDirectory; 288 FtpWebResponse resFtp = null; 289 try 290 { 291 resFtp = (FtpWebResponse)reqFtp.GetResponse(); 292 FtpStatusCode code = resFtp.StatusCode; 293 resFtp.Close(); 294 return true; 295 } 296 catch 297 { 298 if(resFtp != null) resFtp.Close(); 299 return false; 300 } 301 } 302 303 /// <summary> 304 /// 删除文件夹 305 /// </summary> 306 /// <param name="folderName"></param> 307 public bool RemoveDirectory(string folderName) 308 { 309 try 310 { 311 string uri = ftpUri + "/" + folderName; 312 FtpWebRequest reqFTP; 313 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 314 //reqFTP.EnableSsl = false; 315 reqFTP.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 316 reqFTP.KeepAlive = false; 317 reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory; 318 319 string result = String.Empty; 320 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 321 long size = response.ContentLength; 322 Stream datastream = response.GetResponseStream(); 323 StreamReader sr = new StreamReader(datastream); 324 result = sr.ReadToEnd(); 325 sr.Close(); 326 datastream.Close(); 327 response.Close(); 328 return true; 329 } 330 catch (Exception ex) 331 { 332 LogHelper.logger.Error(ex); 333 return false; 334 } 335 } 336 337 public bool DownFile(string fileName, string localName) 338 { 339 try 340 { 341 string uri = string.Empty; 342 if (this.ftpUri.ToString().EndsWith("/")) uri = this.ftpUri + fileName; 343 else uri = this.ftpUri + "/" + fileName; 344 WebClient myWebClient = new WebClient(); 345 myWebClient.Credentials = new NetworkCredential(_ftpUserName, _ftpPassword); 346 myWebClient.DownloadFile(uri, localName); 347 return File.Exists(localName); 348 } 349 catch (Exception ex) 350 { 351 LogHelper.logger.Error(fileName, ex); 352 return false; 353 } 354 } 355 } 356 357 public struct FileStruct 358 { 359 /// <summary> 360 /// 所有者 361 /// </summary> 362 public string Owner; 363 /// <summary> 364 /// 是否为目录 365 /// </summary> 366 public bool IsDirectory; 367 /// <summary> 368 /// 更新时间 369 /// </summary> 370 public string CreateTime; 371 /// <summary> 372 /// 名称 373 /// </summary> 374 public string Name; 375 376 /// <summary> 377 /// 文件大小 378 /// </summary> 379 public int FileSize; 380 381 /// <summary> 382 /// 类型 383 /// </summary> 384 public string FileType; 385 } 386 387 public class DirectoryListParser 388 { 389 private List<FileStruct> _myListArray; 390 391 public DirectoryListParser(string responseString) 392 { 393 _myListArray = GetList(responseString); 394 } 395 396 public List<FileStruct> MyListArray { get { return _myListArray; } } 397 398 /// <summary> 399 /// 文件列表 400 /// </summary> 401 public List<FileStruct> FileList { get { return _myListArray.Where(x => !x.IsDirectory).ToList(); } } 402 403 /// <summary> 404 /// 目录列表 405 /// </summary> 406 public List<FileStruct> DirectoryList { get { return _myListArray.Where(x => x.IsDirectory).ToList(); } } 407 408 private List<FileStruct> GetList(string datastring) 409 { 410 List<FileStruct> myListArray = new List<FileStruct>(); 411 string[] dataRecords = datastring.Split(‘\n‘); 412 int style = GetFileListStyle(dataRecords); 413 foreach (string s in dataRecords) 414 { 415 if (style > 0 && s != "") 416 { 417 FileStruct f = new FileStruct(); 418 f.Name = ".."; 419 if (style == 1) f = ParseFileStructFromUnixStyleRecord(s); 420 else if (style == 2) f = ParseFileStructFromWindowsStyleRecord(s); 421 if (f.Name != "" && f.Name != "." && f.Name != "..") myListArray.Add(f); 422 } 423 } 424 return myListArray; 425 } 426 427 /// <summary> 428 /// 获取文件风格 429 /// </summary> 430 /// <param name="recordList"></param> 431 /// <returns>0-未知,1-Unix风格,2-Windows风格</returns> 432 public int GetFileListStyle(string[] recordList) 433 { 434 foreach (string s in recordList) 435 { 436 if (s.Length > 10 && Regex.IsMatch(s.Substring(0, 10), "(-|d)((-|r)(-|w)(-|x)){3}")) return 1; 437 else if (s.Length > 8 && Regex.IsMatch(s.Substring(0, 8), "[0-9]{2}-[0-9]{2}-[0-9]{2}")) return 2; 438 } 439 return 0; 440 } 441 442 private FileStruct ParseFileStructFromWindowsStyleRecord(string Record) 443 { 444 // Assuming the record style as 445 //文件夹 02-03-04 07:46PM <DIR> Append 446 //文件 02-12-11 02:20AM 26599 xxd.asp 447 FileStruct f = new FileStruct(); 448 string[] arr = Regex.Split(Record.Trim(), "\\s+"); 449 450 f.Name = arr[3]; 451 f.CreateTime = arr[0] + " " + arr[1]; 452 453 if (arr[2] == "<DIR>") 454 { 455 f.FileSize = 0; 456 f.IsDirectory = true; 457 f.FileType = "文件夹"; 458 } 459 else 460 { 461 f.FileSize = int.Parse(arr[2]); 462 f.IsDirectory = false; 463 if (arr[3].IndexOf(".") > -1) f.FileType = arr[3].Split(‘.‘)[1]; 464 else f.FileType = "未知"; 465 } 466 return f; 467 } 468 469 private FileStruct ParseFileStructFromUnixStyleRecord(string record) 470 { 471 ///Assuming record style as 472 /// dr-xr-xr-x 1 owner group 0 Nov 25 2002 bussys 473 FileStruct f = new FileStruct(); 474 if (record[0] == ‘-‘ || record[0] == ‘d‘) 475 {// its a valid file record 476 string processstr = record.Trim(); 477 var flag = processstr.Substring(0, 9); 478 f.IsDirectory = (flag[0] == ‘d‘); 479 processstr = (processstr.Substring(11)).Trim(); 480 _cutSubstringFromStringWithTrim(ref processstr, ‘ ‘, 0); //skip one part 481 f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ‘ ‘, 0); 482 f.CreateTime = getCreateTimeString(record); 483 int fileNameIndex = record.IndexOf(f.CreateTime) + f.CreateTime.Length; 484 f.Name = record.Substring(fileNameIndex).Trim(); //Rest of the part is name 485 } 486 else f.Name = string.Empty; 487 return f; 488 } 489 490 private string getCreateTimeString(string record) 491 { 492 //Does just basic datetime string validation for demo, not an accurate check 493 //on date and time fields 494 string month = "(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)"; 495 string space = @"(\040)+"; 496 string day = "([0-9]|[1-3][0-9])"; 497 string year = "[1-2][0-9]{3}"; 498 string time = "[0-9]{1,2}:[0-9]{2}"; 499 Regex dateTimeRegex = new Regex(month + space + day + space + "(" + year + "|" + time + ")", RegexOptions.IgnoreCase); 500 Match match = dateTimeRegex.Match(record); 501 return match.Value; 502 } 503 504 private string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex) 505 { 506 int pos1 = s.IndexOf(c, startIndex); 507 string retString = s.Substring(0, pos1); 508 s = (s.Substring(pos1)).Trim(); 509 return retString; 510 } 511 } 512 }
原文:https://www.cnblogs.com/chixiner/p/13031458.html