1 using System;
   2 using System.Collections.Generic;
   3 using System.Text;
   4 using System.Net;
   5 using System.IO;
   6 using System.Globalization;
   7 using System.Text.RegularExpressions;
   8 
   9 namespace System.Net.Ftp
  10 {
  11     /// <summary>
  12     /// FTP处理操作类
  13     /// 功能:
  14     /// 下载文件
  15     /// 上传文件
  16     /// 上传文件的进度信息
  17     /// 下载文件的进度信息
  18     /// 删除文件
  19     /// 列出文件
  20     /// 列出目录
  21     /// 进入子目录
  22     /// 退出当前目录返回上一层目录
  23     /// 判断远程文件是否存在
  24     /// 判断远程文件是否存在
  25     /// 删除远程文件    
  26     /// 建立目录
  27     /// 删除目录
  28     /// 文件(目录)改名
  29 
  30     /// </summary>
  31     /// <remarks>
  32     /// 创建人:南疯
  33     /// 创建时间:2007年4月28日
  34     /// </remarks>
  35     #region 文件信息结构
  36     public struct FileStruct
  37     {
  38         public string Flags;
  39         public string Owner;
  40         public string Group;
  41         public bool IsDirectory;
  42         public DateTime CreateTime;
  43         public string Name;
  44     }
  45     public enum FileListStyle
  46     {
  47         UnixStyle,
  48         WindowsStyle,
  49         Unknown
  50     }
  51     #endregion
  52     public class clsFTP
  53     {
  54         #region 属性信息
  55         /// <summary>
  56         /// FTP请求对象
  57         /// </summary>
  58         FtpWebRequest Request = null;
  59         /// <summary>
  60         /// FTP响应对象
  61         /// </summary>
  62         FtpWebResponse Response = null;
  63         /// <summary>
  64         /// FTP服务器地址
  65         /// </summary>
  66         private Uri _Uri;
  67         /// <summary>
  68         /// FTP服务器地址
  69         /// </summary>
  70         public Uri Uri
  71         {
  72             get
  73             {
  74                 if (_DirectoryPath == "/")
  75                 {
  76                     return _Uri;
  77                 }
  78                 else
  79                 {
  80                     string strUri = _Uri.ToString();
  81                     if (strUri.EndsWith("/"))
  82                     {
  83                         strUri = strUri.Substring(0, strUri.Length - 1);
  84                     }
  85                     return new Uri(strUri + this.DirectoryPath);
  86                 }
  87             }
  88             set
  89             {
  90                 if (value.Scheme != Uri.UriSchemeFtp)
  91                 {
  92                     throw new Exception("Ftp 地址格式错误!");
  93                 }
  94                 _Uri = new Uri(value.GetLeftPart(UriPartial.Authority));
  95                 _DirectoryPath = value.AbsolutePath;
  96                 if (!_DirectoryPath.EndsWith("/"))
  97                 {
  98                     _DirectoryPath += "/";
  99                 }
 100             }
 101         }
 102 
 103         /// <summary>
 104         /// 当前工作目录
 105         /// </summary>
 106         private string _DirectoryPath;
 107 
 108         /// <summary>
 109         /// 当前工作目录
 110         /// </summary>
 111         public string DirectoryPath
 112         {
 113             get { return _DirectoryPath; }
 114             set { _DirectoryPath = value; }
 115         }
 116 
 117         /// <summary>
 118         /// FTP登录用户
 119         /// </summary>
 120         private string _UserName;
 121         /// <summary>
 122         /// FTP登录用户
 123         /// </summary>
 124         public string UserName
 125         {
 126             get { return _UserName; }
 127             set { _UserName = value; }
 128         }
 129 
 130         /// <summary>
 131         /// 错误信息
 132         /// </summary>
 133         private string _ErrorMsg;
 134         /// <summary>
 135         /// 错误信息
 136         /// </summary>
 137         public string ErrorMsg
 138         {
 139             get { return _ErrorMsg; }
 140             set { _ErrorMsg = value; }
 141         }
 142 
 143         /// <summary>
 144         /// FTP登录密码
 145         /// </summary>
 146         private string _Password;
 147         /// <summary>
 148         /// FTP登录密码
 149         /// </summary>
 150         public string Password
 151         {
 152             get { return _Password; }
 153             set { _Password = value; }
 154         }
 155 
 156         /// <summary>
 157         /// 连接FTP服务器的代理服务
 158         /// </summary>
 159         private WebProxy _Proxy = null;
 160         /// <summary>
 161         /// 连接FTP服务器的代理服务
 162         /// </summary>
 163         public WebProxy Proxy
 164         {
 165             get
 166             {
 167                 return _Proxy;
 168             }
 169             set
 170             {
 171                 _Proxy = value;
 172             }
 173         }
 174 
 175         /// <summary>
 176         /// 是否需要删除临时文件
 177         /// </summary>
 178         private bool _isDeleteTempFile = false;
 179         /// <summary>
 180         /// 异步上传所临时生成的文件
 181         /// </summary>
 182         private string _UploadTempFile = "";
 183         #endregion
 184         #region 事件
 185         public delegate void De_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e);
 186         public delegate void De_DownloadDataCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e);
 187         public delegate void De_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e);
 188         public delegate void De_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e);
 189 
 190         /// <summary>
 191         /// 异步下载进度发生改变触发的事件
 192         /// </summary>
 193         public event De_DownloadProgressChanged DownloadProgressChanged;
 194         /// <summary>
 195         /// 异步下载文件完成之后触发的事件
 196         /// </summary>
 197         public event De_DownloadDataCompleted DownloadDataCompleted;
 198         /// <summary>
 199         /// 异步上传进度发生改变触发的事件
 200         /// </summary>
 201         public event De_UploadProgressChanged UploadProgressChanged;
 202         /// <summary>
 203         /// 异步上传文件完成之后触发的事件
 204         /// </summary>
 205         public event De_UploadFileCompleted UploadFileCompleted;
 206         #endregion
 207         #region 构造析构函数
 208         /// <summary>
 209         /// 构造函数
 210         /// </summary>
 211         /// <param name="FtpUri">FTP地址</param>
 212         /// <param name="strUserName">登录用户名</param>
 213         /// <param name="strPassword">登录密码</param>
 214         public clsFTP(Uri FtpUri, string strUserName, string strPassword)
 215         {
 216             this._Uri = new Uri(FtpUri.GetLeftPart(UriPartial.Authority));
 217             _DirectoryPath = FtpUri.AbsolutePath;
 218             if (!_DirectoryPath.EndsWith("/"))
 219             {
 220                 _DirectoryPath += "/";
 221             }
 222             this._UserName = strUserName;
 223             this._Password = strPassword;
 224             this._Proxy = null;
 225         }
 226         /// <summary>
 227         /// 构造函数
 228         /// </summary>
 229         /// <param name="FtpUri">FTP地址</param>
 230         /// <param name="strUserName">登录用户名</param>
 231         /// <param name="strPassword">登录密码</param>
 232         /// <param name="objProxy">连接代理</param>
 233         public clsFTP(Uri FtpUri, string strUserName, string strPassword, WebProxy objProxy)
 234         {
 235             this._Uri = new Uri(FtpUri.GetLeftPart(UriPartial.Authority));
 236             _DirectoryPath = FtpUri.AbsolutePath;
 237             if (!_DirectoryPath.EndsWith("/"))
 238             {
 239                 _DirectoryPath += "/";
 240             }
 241             this._UserName = strUserName;
 242             this._Password = strPassword;
 243             this._Proxy = objProxy;
 244         }
 245         /// <summary>
 246         /// 构造函数
 247         /// </summary>
 248         public clsFTP()
 249         {
 250             this._UserName = "anonymous";  //匿名用户
 251             this._Password = "@anonymous";
 252             this._Uri = null;
 253             this._Proxy = null;
 254         }
 255 
 256         /// <summary>
 257         /// 析构函数
 258         /// </summary>
 259         ~clsFTP()
 260         {
 261             if (Response != null)
 262             {
 263                 Response.Close();
 264                 Response = null;
 265             }
 266             if (Request != null)
 267             {
 268                 Request.Abort();
 269                 Request = null;
 270             }
 271         }
 272         #endregion
 273         #region 建立连接
 274         /// <summary>
 275         /// 建立FTP链接,返回响应对象
 276         /// </summary>
 277         /// <param name="uri">FTP地址</param>
 278         /// <param name="FtpMathod">操作命令</param>
 279         private FtpWebResponse Open(Uri uri, string FtpMathod)
 280         {
 281             try
 282             {
 283                 Request = (FtpWebRequest) WebRequest.Create(uri);
 284                 Request.Method = FtpMathod;
 285                 Request.UseBinary = true;
 286                 Request.Credentials = new NetworkCredential(this.UserName, this.Password);
 287                 if (this.Proxy != null)
 288                 {
 289                     Request.Proxy = this.Proxy;
 290                 }
 291                 return (FtpWebResponse) Request.GetResponse();
 292             }
 293             catch (Exception ep)
 294             {
 295                 ErrorMsg = ep.ToString();
 296                 throw ep;
 297             }
 298         }
 299         /// <summary>
 300         /// 建立FTP链接,返回请求对象
 301         /// </summary>
 302         /// <param name="uri">FTP地址</param>
 303         /// <param name="FtpMathod">操作命令</param>
 304         private FtpWebRequest OpenRequest(Uri uri, string FtpMathod)
 305         {
 306             try
 307             {
 308                 Request = (FtpWebRequest) WebRequest.Create(uri);
 309                 Request.Method = FtpMathod;
 310                 Request.UseBinary = true;
 311                 Request.Credentials = new NetworkCredential(this.UserName, this.Password);
 312                 if (this.Proxy != null)
 313                 {
 314                     Request.Proxy = this.Proxy;
 315                 }
 316                 return Request;
 317             }
 318             catch (Exception ep)
 319             {
 320                 ErrorMsg = ep.ToString();
 321                 throw ep;
 322             }
 323         }
 324         #endregion
 325         #region 下载文件
 326 
 327         /// <summary>
 328         /// 从FTP服务器下载文件,使用与远程文件同名的文件名来保存文件
 329         /// </summary>
 330         /// <param name="RemoteFileName">远程文件名</param>
 331         /// <param name="LocalPath">本地路径</param>
 332 
 333         public bool DownloadFile(string RemoteFileName, string LocalPath)
 334         {
 335             return DownloadFile(RemoteFileName, LocalPath, RemoteFileName);
 336         }
 337         /// <summary>
 338         /// 从FTP服务器下载文件,指定本地路径和本地文件名
 339         /// </summary>
 340         /// <param name="RemoteFileName">远程文件名</param>
 341         /// <param name="LocalPath">本地路径</param>
 342         /// <param name="LocalFilePath">保存文件的本地路径,后面带有"\"</param>
 343         /// <param name="LocalFileName">保存本地的文件名</param>
 344         public bool DownloadFile(string RemoteFileName, string LocalPath, string LocalFileName)
 345         {
 346             byte[] bt = null;
 347             try
 348             {
 349                 if (!IsValidFileChars(RemoteFileName) || !IsValidFileChars(LocalFileName) || !IsValidPathChars(LocalPath))
 350                 {
 351                     throw new Exception("非法文件名或目录名!");
 352                 }
 353                 if (!Directory.Exists(LocalPath))
 354                 {
 355                     throw new Exception("本地文件路径不存在!");
 356                 }
 357 
 358                 string LocalFullPath = Path.Combine(LocalPath, LocalFileName);
 359                 if (File.Exists(LocalFullPath))
 360                 {
 361                     throw new Exception("当前路径下已经存在同名文件!");
 362                 }
 363                 bt = DownloadFile(RemoteFileName);
 364                 if (bt != null)
 365                 {
 366                     FileStream stream = new FileStream(LocalFullPath, FileMode.Create);
 367                     stream.Write(bt, 0, bt.Length);
 368                     stream.Flush();
 369                     stream.Close();
 370                     return true;
 371                 }
 372                 else
 373                 {
 374                     return false;
 375                 }
 376             }
 377             catch (Exception ep)
 378             {
 379                 ErrorMsg = ep.ToString();
 380                 throw ep;
 381             }
 382         }
 383 
 384         /// <summary>
 385         /// 从FTP服务器下载文件,返回文件二进制数据
 386         /// </summary>
 387         /// <param name="RemoteFileName">远程文件名</param>
 388         public byte[] DownloadFile(string RemoteFileName)
 389         {
 390             try
 391             {
 392                 if (!IsValidFileChars(RemoteFileName))
 393                 {
 394                     throw new Exception("非法文件名或目录名!");
 395                 }
 396                 Response = Open(new Uri(this.Uri.ToString() + RemoteFileName), WebRequestMethods.Ftp.DownloadFile);
 397                 Stream Reader = Response.GetResponseStream();
 398 
 399                 MemoryStream mem = new MemoryStream(1024 * 500);
 400                 byte[] buffer = new byte[1024];
 401                 int bytesRead = 0;
 402                 int TotalByteRead = 0;
 403                 while (true)
 404                 {
 405                     bytesRead = Reader.Read(buffer, 0, buffer.Length);
 406                     TotalByteRead += bytesRead;
 407                     if (bytesRead == 0)
 408                         break;
 409                     mem.Write(buffer, 0, bytesRead);
 410                 }
 411                 if (mem.Length > 0)
 412                 {
 413                     return mem.ToArray();
 414                 }
 415                 else
 416                 {
 417                     return null;
 418                 }
 419             }
 420             catch (Exception ep)
 421             {
 422                 ErrorMsg = ep.ToString();
 423                 throw ep;
 424             }
 425         }
 426         #endregion
 427         #region 异步下载文件
 428         /// <summary>
 429         /// 从FTP服务器异步下载文件,指定本地路径和本地文件名
 430         /// </summary>
 431         /// <param name="RemoteFileName">远程文件名</param>        
 432         /// <param name="LocalPath">保存文件的本地路径,后面带有"\"</param>
 433         /// <param name="LocalFileName">保存本地的文件名</param>
 434         public void DownloadFileAsync(string RemoteFileName, string LocalPath, string LocalFileName)
 435         {
 436             byte[] bt = null;
 437             try
 438             {
 439                 if (!IsValidFileChars(RemoteFileName) || !IsValidFileChars(LocalFileName) || !IsValidPathChars(LocalPath))
 440                 {
 441                     throw new Exception("非法文件名或目录名!");
 442                 }
 443                 if (!Directory.Exists(LocalPath))
 444                 {
 445                     throw new Exception("本地文件路径不存在!");
 446                 }
 447 
 448                 string LocalFullPath = Path.Combine(LocalPath, LocalFileName);
 449                 if (File.Exists(LocalFullPath))
 450                 {
 451                     throw new Exception("当前路径下已经存在同名文件!");
 452                 }
 453                 DownloadFileAsync(RemoteFileName, LocalFullPath);
 454 
 455             }
 456             catch (Exception ep)
 457             {
 458                 ErrorMsg = ep.ToString();
 459                 throw ep;
 460             }
 461         }
 462 
 463         /// <summary>
 464         /// 从FTP服务器异步下载文件,指定本地完整路径文件名
 465         /// </summary>
 466         /// <param name="RemoteFileName">远程文件名</param>
 467         /// <param name="LocalFullPath">本地完整路径文件名</param>
 468         public void DownloadFileAsync(string RemoteFileName, string LocalFullPath)
 469         {
 470             try
 471             {
 472                 if (!IsValidFileChars(RemoteFileName))
 473                 {
 474                     throw new Exception("非法文件名或目录名!");
 475                 }
 476                 if (File.Exists(LocalFullPath))
 477                 {
 478                     throw new Exception("当前路径下已经存在同名文件!");
 479                 }
 480                 MyWebClient client = new MyWebClient();
 481 
 482                 client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
 483                 client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);
 484                 client.Credentials = new NetworkCredential(this.UserName, this.Password);
 485                 if (this.Proxy != null)
 486                 {
 487                     client.Proxy = this.Proxy;
 488                 }
 489                 client.DownloadFileAsync(new Uri(this.Uri.ToString() + RemoteFileName), LocalFullPath);
 490             }
 491             catch (Exception ep)
 492             {
 493                 ErrorMsg = ep.ToString();
 494                 throw ep;
 495             }
 496         }
 497 
 498         /// <summary>
 499         /// 异步下载文件完成之后触发的事件
 500         /// </summary>
 501         /// <param name="sender">下载对象</param>
 502         /// <param name="e">数据信息对象</param>
 503         void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
 504         {
 505             if (DownloadDataCompleted != null)
 506             {
 507                 DownloadDataCompleted(sender, e);
 508             }
 509         }
 510 
 511         /// <summary>
 512         /// 异步下载进度发生改变触发的事件
 513         /// </summary>
 514         /// <param name="sender">下载对象</param>
 515         /// <param name="e">进度信息对象</param>
 516         void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
 517         {
 518             if (DownloadProgressChanged != null)
 519             {
 520                 DownloadProgressChanged(sender, e);
 521             }
 522         }
 523         #endregion
 524         #region 上传文件
 525         /// <summary>
 526         /// 上传文件到FTP服务器
 527         /// </summary>
 528         /// <param name="LocalFullPath">本地带有完整路径的文件名</param>
 529         public bool UploadFile(string LocalFullPath)
 530         {
 531             return UploadFile(LocalFullPath, Path.GetFileName(LocalFullPath), false);
 532         }
 533         /// <summary>
 534         /// 上传文件到FTP服务器
 535         /// </summary>
 536         /// <param name="LocalFullPath">本地带有完整路径的文件</param>
 537         /// <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
 538         public bool UploadFile(string LocalFullPath, bool OverWriteRemoteFile)
 539         {
 540             return UploadFile(LocalFullPath, Path.GetFileName(LocalFullPath), OverWriteRemoteFile);
 541         }
 542         /// <summary>
 543         /// 上传文件到FTP服务器
 544         /// </summary>
 545         /// <param name="LocalFullPath">本地带有完整路径的文件</param>
 546         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 547         public bool UploadFile(string LocalFullPath, string RemoteFileName)
 548         {
 549             return UploadFile(LocalFullPath, RemoteFileName, false);
 550         }
 551         /// <summary>
 552         /// 上传文件到FTP服务器
 553         /// </summary>
 554         /// <param name="LocalFullPath">本地带有完整路径的文件名</param>
 555         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 556         /// <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
 557         public bool UploadFile(string LocalFullPath, string RemoteFileName, bool OverWriteRemoteFile)
 558         {
 559             try
 560             {
 561                 if (!IsValidFileChars(RemoteFileName) || !IsValidFileChars(Path.GetFileName(LocalFullPath)) || !IsValidPathChars(Path.GetDirectoryName(LocalFullPath)))
 562                 {
 563                     throw new Exception("非法文件名或目录名!");
 564                 }
 565                 if (File.Exists(LocalFullPath))
 566                 {
 567                     FileStream Stream = new FileStream(LocalFullPath, FileMode.Open, FileAccess.Read);
 568                     byte[] bt = new byte[Stream.Length];
 569                     Stream.Read(bt, 0, (Int32) Stream.Length);   //注意,因为Int32的最大限制,最大上传文件只能是大约2G多一点
 570                     Stream.Close();
 571                     return UploadFile(bt, RemoteFileName, OverWriteRemoteFile);
 572                 }
 573                 else
 574                 {
 575                     throw new Exception("本地文件不存在!");
 576                 }
 577             }
 578             catch (Exception ep)
 579             {
 580                 ErrorMsg = ep.ToString();
 581                 throw ep;
 582             }
 583         }
 584         /// <summary>
 585         /// 上传文件到FTP服务器
 586         /// </summary>
 587         /// <param name="FileBytes">上传的二进制数据</param>
 588         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 589         public bool UploadFile(byte[] FileBytes, string RemoteFileName)
 590         {
 591             if (!IsValidFileChars(RemoteFileName))
 592             {
 593                 throw new Exception("非法文件名或目录名!");
 594             }
 595             return UploadFile(FileBytes, RemoteFileName, false);
 596         }
 597         /// <summary>
 598         /// 上传文件到FTP服务器
 599         /// </summary>
 600         /// <param name="FileBytes">文件二进制内容</param>
 601         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 602         /// <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
 603         public bool UploadFile(byte[] FileBytes, string RemoteFileName, bool OverWriteRemoteFile)
 604         {
 605             try
 606             {
 607                 if (!IsValidFileChars(RemoteFileName))
 608                 {
 609                     throw new Exception("非法文件名!");
 610                 }
 611                 if (!OverWriteRemoteFile && FileExist(RemoteFileName))
 612                 {
 613                     throw new Exception("FTP服务上面已经存在同名文件!");
 614                 }
 615                 Response = Open(new Uri(this.Uri.ToString() + RemoteFileName), WebRequestMethods.Ftp.UploadFile);
 616                 Stream requestStream = Request.GetRequestStream();
 617                 MemoryStream mem = new MemoryStream(FileBytes);
 618 
 619                 byte[] buffer = new byte[1024];
 620                 int bytesRead = 0;
 621                 int TotalRead = 0;
 622                 while (true)
 623                 {
 624                     bytesRead = mem.Read(buffer, 0, buffer.Length);
 625                     if (bytesRead == 0)
 626                         break;
 627                     TotalRead += bytesRead;
 628                     requestStream.Write(buffer, 0, bytesRead);
 629                 }
 630                 requestStream.Close();
 631                 Response = (FtpWebResponse) Request.GetResponse();
 632                 mem.Close();
 633                 mem.Dispose();
 634                 FileBytes = null;
 635                 return true;
 636             }
 637             catch (Exception ep)
 638             {
 639                 ErrorMsg = ep.ToString();
 640                 throw ep;
 641             }
 642         }
 643         #endregion
 644         #region 异步上传文件
 645         /// <summary>
 646         /// 异步上传文件到FTP服务器
 647         /// </summary>
 648         /// <param name="LocalFullPath">本地带有完整路径的文件名</param>
 649         public void UploadFileAsync(string LocalFullPath)
 650         {
 651             UploadFileAsync(LocalFullPath, Path.GetFileName(LocalFullPath), false);
 652         }
 653         /// <summary>
 654         /// 异步上传文件到FTP服务器
 655         /// </summary>
 656         /// <param name="LocalFullPath">本地带有完整路径的文件</param>
 657         /// <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
 658         public void UploadFileAsync(string LocalFullPath, bool OverWriteRemoteFile)
 659         {
 660             UploadFileAsync(LocalFullPath, Path.GetFileName(LocalFullPath), OverWriteRemoteFile);
 661         }
 662         /// <summary>
 663         /// 异步上传文件到FTP服务器
 664         /// </summary>
 665         /// <param name="LocalFullPath">本地带有完整路径的文件</param>
 666         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 667         public void UploadFileAsync(string LocalFullPath, string RemoteFileName)
 668         {
 669             UploadFileAsync(LocalFullPath, RemoteFileName, false);
 670         }
 671         /// <summary>
 672         /// 异步上传文件到FTP服务器
 673         /// </summary>
 674         /// <param name="LocalFullPath">本地带有完整路径的文件名</param>
 675         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 676         /// <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
 677         public void UploadFileAsync(string LocalFullPath, string RemoteFileName, bool OverWriteRemoteFile)
 678         {
 679             try
 680             {
 681                 if (!IsValidFileChars(RemoteFileName) || !IsValidFileChars(Path.GetFileName(LocalFullPath)) || !IsValidPathChars(Path.GetDirectoryName(LocalFullPath)))
 682                 {
 683                     throw new Exception("非法文件名或目录名!");
 684                 }
 685                 if (!OverWriteRemoteFile && FileExist(RemoteFileName))
 686                 {
 687                     throw new Exception("FTP服务上面已经存在同名文件!");
 688                 }
 689                 if (File.Exists(LocalFullPath))
 690                 {
 691                     MyWebClient client = new MyWebClient();
 692 
 693                     client.UploadProgressChanged += new UploadProgressChangedEventHandler(client_UploadProgressChanged);
 694                     client.UploadFileCompleted += new UploadFileCompletedEventHandler(client_UploadFileCompleted);
 695                     client.Credentials = new NetworkCredential(this.UserName, this.Password);
 696                     if (this.Proxy != null)
 697                     {
 698                         client.Proxy = this.Proxy;
 699                     }
 700                     client.UploadFileAsync(new Uri(this.Uri.ToString() + RemoteFileName), LocalFullPath);
 701 
 702                 }
 703                 else
 704                 {
 705                     throw new Exception("本地文件不存在!");
 706                 }
 707             }
 708             catch (Exception ep)
 709             {
 710                 ErrorMsg = ep.ToString();
 711                 throw ep;
 712             }
 713         }
 714         /// <summary>
 715         /// 异步上传文件到FTP服务器
 716         /// </summary>
 717         /// <param name="FileBytes">上传的二进制数据</param>
 718         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 719         public void UploadFileAsync(byte[] FileBytes, string RemoteFileName)
 720         {
 721             if (!IsValidFileChars(RemoteFileName))
 722             {
 723                 throw new Exception("非法文件名或目录名!");
 724             }
 725             UploadFileAsync(FileBytes, RemoteFileName, false);
 726         }
 727         /// <summary>
 728         /// 异步上传文件到FTP服务器
 729         /// </summary>
 730         /// <param name="FileBytes">文件二进制内容</param>
 731         /// <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
 732         /// <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
 733         public void UploadFileAsync(byte[] FileBytes, string RemoteFileName, bool OverWriteRemoteFile)
 734         {
 735             try
 736             {
 737 
 738                 if (!IsValidFileChars(RemoteFileName))
 739                 {
 740                     throw new Exception("非法文件名!");
 741                 }
 742                 if (!OverWriteRemoteFile && FileExist(RemoteFileName))
 743                 {
 744                     throw new Exception("FTP服务上面已经存在同名文件!");
 745                 }
 746                 string TempPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Templates);
 747                 if (!TempPath.EndsWith("\\"))
 748                 {
 749                     TempPath += "\\";
 750                 }
 751                 string TempFile = TempPath + Path.GetRandomFileName();
 752                 TempFile = Path.ChangeExtension(TempFile, Path.GetExtension(RemoteFileName));
 753                 FileStream Stream = new FileStream(TempFile, FileMode.CreateNew, FileAccess.Write);
 754                 Stream.Write(FileBytes, 0, FileBytes.Length);   //注意,因为Int32的最大限制,最大上传文件只能是大约2G多一点
 755                 Stream.Flush();
 756                 Stream.Close();
 757                 Stream.Dispose();
 758                 _isDeleteTempFile = true;
 759                 _UploadTempFile = TempFile;
 760                 FileBytes = null;
 761                 UploadFileAsync(TempFile, RemoteFileName, OverWriteRemoteFile);
 762 
 763 
 764 
 765             }
 766             catch (Exception ep)
 767             {
 768                 ErrorMsg = ep.ToString();
 769                 throw ep;
 770             }
 771         }
 772 
 773         /// <summary>
 774         /// 异步上传文件完成之后触发的事件
 775         /// </summary>
 776         /// <param name="sender">下载对象</param>
 777         /// <param name="e">数据信息对象</param>
 778         void client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
 779         {
 780             if (_isDeleteTempFile)
 781             {
 782                 if (File.Exists(_UploadTempFile))
 783                 {
 784                     File.SetAttributes(_UploadTempFile, FileAttributes.Normal);
 785                     File.Delete(_UploadTempFile);
 786                 }
 787                 _isDeleteTempFile = false;
 788             }
 789             if (UploadFileCompleted != null)
 790             {
 791                 UploadFileCompleted(sender, e);
 792             }
 793         }
 794 
 795         /// <summary>
 796         /// 异步上传进度发生改变触发的事件
 797         /// </summary>
 798         /// <param name="sender">下载对象</param>
 799         /// <param name="e">进度信息对象</param>
 800         void client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
 801         {
 802             if (UploadProgressChanged != null)
 803             {
 804                 UploadProgressChanged(sender, e);
 805             }
 806         }
 807         #endregion
 808         #region 列出目录文件信息
 809         /// <summary>
 810         /// 列出FTP服务器上面当前目录的所有文件和目录
 811         /// </summary>
 812         public FileStruct[] ListFilesAndDirectories()
 813         {
 814             Response = Open(this.Uri, WebRequestMethods.Ftp.ListDirectoryDetails);
 815             StreamReader stream = new StreamReader(Response.GetResponseStream(), Encoding.Default);
 816             string Datastring = stream.ReadToEnd();
 817             FileStruct[] list = GetList(Datastring);
 818             return list;
 819         }
 820         /// <summary>
 821         /// 列出FTP服务器上面当前目录的所有文件
 822         /// </summary>
 823         public FileStruct[] ListFiles()
 824         {
 825             FileStruct[] listAll = ListFilesAndDirectories();
 826             List<FileStruct> listFile = new List<FileStruct>();
 827             foreach (FileStruct file in listAll)
 828             {
 829                 if (!file.IsDirectory)
 830                 {
 831                     listFile.Add(file);
 832                 }
 833             }
 834             return listFile.ToArray();
 835         }
 836 
 837         /// <summary>
 838         /// 列出FTP服务器上面当前目录的所有的目录
 839         /// </summary>
 840         public FileStruct[] ListDirectories()
 841         {
 842             FileStruct[] listAll = ListFilesAndDirectories();
 843             List<FileStruct> listDirectory = new List<FileStruct>();
 844             foreach (FileStruct file in listAll)
 845             {
 846                 if (file.IsDirectory)
 847                 {
 848                     listDirectory.Add(file);
 849                 }
 850             }
 851             return listDirectory.ToArray();
 852         }
 853         /// <summary>
 854         /// 获得文件和目录列表
 855         /// </summary>
 856         /// <param name="datastring">FTP返回的列表字符信息</param>
 857         private FileStruct[] GetList(string datastring)
 858         {
 859             List<FileStruct> myListArray = new List<FileStruct>();
 860             string[] dataRecords = datastring.Split('\n');
 861             FileListStyle _directoryListStyle = GuessFileListStyle(dataRecords);
 862             foreach (string s in dataRecords)
 863             {
 864                 if (_directoryListStyle != FileListStyle.Unknown && s != "")
 865                 {
 866                     FileStruct f = new FileStruct();
 867                     f.Name = "..";
 868                     switch (_directoryListStyle)
 869                     {
 870                     case FileListStyle.UnixStyle:
 871                         f = ParseFileStructFromUnixStyleRecord(s);
 872                         break;
 873                     case FileListStyle.WindowsStyle:
 874                         f = ParseFileStructFromWindowsStyleRecord(s);
 875                         break;
 876                     }
 877                     if (!(f.Name == "." || f.Name == ".."))
 878                     {
 879                         myListArray.Add(f);
 880                     }
 881                 }
 882             }
 883             return myListArray.ToArray();
 884         }
 885 
 886         /// <summary>
 887         /// 从Windows格式中返回文件信息
 888         /// </summary>
 889         /// <param name="Record">文件信息</param>
 890         private FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
 891         {
 892             FileStruct f = new FileStruct();
 893             string processstr = Record.Trim();
 894             string dateStr = processstr.Substring(0, 8);
 895             processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
 896             string timeStr = processstr.Substring(0, 7);
 897             processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
 898             DateTimeFormatInfo myDTFI = new CultureInfo("en-US", false).DateTimeFormat;
 899             myDTFI.ShortTimePattern = "t";
 900             f.CreateTime = DateTime.Parse(dateStr + " " + timeStr, myDTFI);
 901             if (processstr.Substring(0, 5) == "<DIR>")
 902             {
 903                 f.IsDirectory = true;
 904                 processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
 905             }
 906             else
 907             {
 908                 string[] strs = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);   // true);
 909                 processstr = strs[1];
 910                 f.IsDirectory = false;
 911             }
 912             f.Name = processstr;
 913             return f;
 914         }
 915 
 916 
 917         /// <summary>
 918         /// 判断文件列表的方式Window方式还是Unix方式
 919         /// </summary>
 920         /// <param name="recordList">文件信息列表</param>
 921         private FileListStyle GuessFileListStyle(string[] recordList)
 922         {
 923             foreach (string s in recordList)
 924             {
 925                 if (s.Length > 10
 926                  && Regex.IsMatch(s.Substring(0, 10), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)"))
 927                 {
 928                     return FileListStyle.UnixStyle;
 929                 }
 930                 else if (s.Length > 8
 931                  && Regex.IsMatch(s.Substring(0, 8), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"))
 932                 {
 933                     return FileListStyle.WindowsStyle;
 934                 }
 935             }
 936             return FileListStyle.Unknown;
 937         }
 938 
 939         /// <summary>
 940         /// 从Unix格式中返回文件信息
 941         /// </summary>
 942         /// <param name="Record">文件信息</param>
 943         private FileStruct ParseFileStructFromUnixStyleRecord(string Record)
 944         {
 945             FileStruct f = new FileStruct();
 946             string processstr = Record.Trim();
 947             f.Flags = processstr.Substring(0, 10);
 948             f.IsDirectory = (f.Flags[0] == 'd');
 949             processstr = (processstr.Substring(11)).Trim();
 950             _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);   //跳过一部分
 951             f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
 952             f.Group = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
 953             _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);   //跳过一部分
 954             string yearOrTime = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2];
 955             if (yearOrTime.IndexOf(":") >= 0)  //time
 956             {
 957                 processstr = processstr.Replace(yearOrTime, DateTime.Now.Year.ToString());
 958             }
 959             f.CreateTime = DateTime.Parse(_cutSubstringFromStringWithTrim(ref processstr, ' ', 8));
 960             f.Name = processstr;   //最后就是名称
 961             return f;
 962         }
 963 
 964         /// <summary>
 965         /// 按照一定的规则进行字符串截取
 966         /// </summary>
 967         /// <param name="s">截取的字符串</param>
 968         /// <param name="c">查找的字符</param>
 969         /// <param name="startIndex">查找的位置</param>
 970         private string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex)
 971         {
 972             int pos1 = s.IndexOf(c, startIndex);
 973             string retString = s.Substring(0, pos1);
 974             s = (s.Substring(pos1)).Trim();
 975             return retString;
 976         }
 977         #endregion
 978         #region 目录或文件存在的判断
 979         /// <summary>
 980         /// 判断当前目录下指定的子目录是否存在
 981         /// </summary>
 982         /// <param name="RemoteDirectoryName">指定的目录名</param>
 983         public bool DirectoryExist(string RemoteDirectoryName)
 984         {
 985             try
 986             {
 987                 if (!IsValidPathChars(RemoteDirectoryName))
 988                 {
 989                     throw new Exception("目录名非法!");
 990                 }
 991                 FileStruct[] listDir = ListDirectories();
 992                 foreach (FileStruct dir in listDir)
 993                 {
 994                     if (dir.Name == RemoteDirectoryName)
 995                     {
 996                         return true;
 997                     }
 998                 }
 999                 return false;
1000             }
1001             catch (Exception ep)
1002             {
1003                 ErrorMsg = ep.ToString();
1004                 throw ep;
1005             }
1006         }
1007         /// <summary>
1008         /// 判断一个远程文件是否存在服务器当前目录下面
1009         /// </summary>
1010         /// <param name="RemoteFileName">远程文件名</param>
1011         public bool FileExist(string RemoteFileName)
1012         {
1013             try
1014             {
1015                 if (!IsValidFileChars(RemoteFileName))
1016                 {
1017                     throw new Exception("文件名非法!");
1018                 }
1019                 FileStruct[] listFile = ListFiles();
1020                 foreach (FileStruct file in listFile)
1021                 {
1022                     if (file.Name == RemoteFileName)
1023                     {
1024                         return true;
1025                     }
1026                 }
1027                 return false;
1028             }
1029             catch (Exception ep)
1030             {
1031                 ErrorMsg = ep.ToString();
1032                 throw ep;
1033             }
1034         }
1035         #endregion
1036         #region 删除文件
1037         /// <summary>
1038         /// 从FTP服务器上面删除一个文件
1039         /// </summary>
1040         /// <param name="RemoteFileName">远程文件名</param>
1041         public void DeleteFile(string RemoteFileName)
1042         {
1043             try
1044             {
1045                 if (!IsValidFileChars(RemoteFileName))
1046                 {
1047                     throw new Exception("文件名非法!");
1048                 }
1049                 Response = Open(new Uri(this.Uri.ToString() + RemoteFileName), WebRequestMethods.Ftp.DeleteFile);
1050             }
1051             catch (Exception ep)
1052             {
1053                 ErrorMsg = ep.ToString();
1054                 throw ep;
1055             }
1056         }
1057         #endregion
1058         #region 重命名文件
1059         /// <summary>
1060         /// 更改一个文件的名称或一个目录的名称
1061         /// </summary>
1062         /// <param name="RemoteFileName">原始文件或目录名称</param>
1063         /// <param name="NewFileName">新的文件或目录的名称</param>
1064         public bool ReName(string RemoteFileName, string NewFileName)
1065         {
1066             try
1067             {
1068                 if (!IsValidFileChars(RemoteFileName) || !IsValidFileChars(NewFileName))
1069                 {
1070                     throw new Exception("文件名非法!");
1071                 }
1072                 if (RemoteFileName == NewFileName)
1073                 {
1074                     return true;
1075                 }
1076                 if (FileExist(RemoteFileName))
1077                 {
1078                     Request = OpenRequest(new Uri(this.Uri.ToString() + RemoteFileName), WebRequestMethods.Ftp.Rename);
1079                     Request.RenameTo = NewFileName;
1080                     Response = (FtpWebResponse) Request.GetResponse();
1081 
1082                 }
1083                 else
1084                 {
1085                     throw new Exception("文件在服务器上不存在!");
1086                 }
1087                 return true;
1088             }
1089             catch (Exception ep)
1090             {
1091                 ErrorMsg = ep.ToString();
1092                 throw ep;
1093             }
1094         }
1095         #endregion
1096         #region 拷贝、移动文件
1097         /// <summary>
1098         /// 把当前目录下面的一个文件拷贝到服务器上面另外的目录中,注意,拷贝文件之后,当前工作目录还是文件原来所在的目录
1099         /// </summary>
1100         /// <param name="RemoteFile">当前目录下的文件名</param>
1101         /// <param name="DirectoryName">新目录名称。
1102         /// 说明:如果新目录是当前目录的子目录,则直接指定子目录。如: SubDirectory1/SubDirectory2 ;
1103         /// 如果新目录不是当前目录的子目录,则必须从根目录一级一级的指定。如: ./NewDirectory/SubDirectory1/SubDirectory2
1104         /// </param>
1105         /// <returns></returns>
1106         public bool CopyFileToAnotherDirectory(string RemoteFile, string DirectoryName)
1107         {
1108             string CurrentWorkDir = this.DirectoryPath;
1109             try
1110             {
1111                 byte[] bt = DownloadFile(RemoteFile);
1112                 GotoDirectory(DirectoryName);
1113                 bool Success = UploadFile(bt, RemoteFile, false);
1114                 this.DirectoryPath = CurrentWorkDir;
1115                 return Success;
1116             }
1117             catch (Exception ep)
1118             {
1119                 this.DirectoryPath = CurrentWorkDir;
1120                 ErrorMsg = ep.ToString();
1121                 throw ep;
1122             }
1123         }
1124         /// <summary>
1125         /// 把当前目录下面的一个文件移动到服务器上面另外的目录中,注意,移动文件之后,当前工作目录还是文件原来所在的目录
1126         /// </summary>
1127         /// <param name="RemoteFile">当前目录下的文件名</param>
1128         /// <param name="DirectoryName">新目录名称。
1129         /// 说明:如果新目录是当前目录的子目录,则直接指定子目录。如: SubDirectory1/SubDirectory2 ;
1130         /// 如果新目录不是当前目录的子目录,则必须从根目录一级一级的指定。如: ./NewDirectory/SubDirectory1/SubDirectory2
1131         /// </param>
1132         /// <returns></returns>
1133         public bool MoveFileToAnotherDirectory(string RemoteFile, string DirectoryName)
1134         {
1135             string CurrentWorkDir = this.DirectoryPath;
1136             try
1137             {
1138                 if (DirectoryName == "")
1139                     return false;
1140                 if (!DirectoryName.StartsWith("/"))
1141                     DirectoryName = "/" + DirectoryName;
1142                 if (!DirectoryName.EndsWith("/"))
1143                     DirectoryName += "/";
1144                 bool Success = ReName(RemoteFile, DirectoryName + RemoteFile);
1145                 this.DirectoryPath = CurrentWorkDir;
1146                 return Success;
1147             }
1148             catch (Exception ep)
1149             {
1150                 this.DirectoryPath = CurrentWorkDir;
1151                 ErrorMsg = ep.ToString();
1152                 throw ep;
1153             }
1154         }
1155         #endregion
1156         #region 建立、删除子目录
1157         /// <summary>
1158         /// 在FTP服务器上当前工作目录建立一个子目录
1159         /// </summary>
1160         /// <param name="DirectoryName">子目录名称</param>
1161         public bool MakeDirectory(string DirectoryName)
1162         {
1163             try
1164             {
1165                 if (!IsValidPathChars(DirectoryName))
1166                 {
1167                     throw new Exception("目录名非法!");
1168                 }
1169                 if (DirectoryExist(DirectoryName))
1170                 {
1171                     throw new Exception("服务器上面已经存在同名的文件名或目录名!");
1172                 }
1173                 Response = Open(new Uri(this.Uri.ToString() + DirectoryName), WebRequestMethods.Ftp.MakeDirectory);
1174                 return true;
1175             }
1176             catch (Exception ep)
1177             {
1178                 ErrorMsg = ep.ToString();
1179                 throw ep;
1180             }
1181         }
1182         /// <summary>
1183         /// 从当前工作目录中删除一个子目录
1184         /// </summary>
1185         /// <param name="DirectoryName">子目录名称</param>
1186         public bool RemoveDirectory(string DirectoryName)
1187         {
1188             try
1189             {
1190                 if (!IsValidPathChars(DirectoryName))
1191                 {
1192                     throw new Exception("目录名非法!");
1193                 }
1194                 if (!DirectoryExist(DirectoryName))
1195                 {
1196                     throw new Exception("服务器上面不存在指定的文件名或目录名!");
1197                 }
1198                 Response = Open(new Uri(this.Uri.ToString() + DirectoryName), WebRequestMethods.Ftp.RemoveDirectory);
1199                 return true;
1200             }
1201             catch (Exception ep)
1202             {
1203                 ErrorMsg = ep.ToString();
1204                 throw ep;
1205             }
1206         }
1207         #endregion
1208         #region 文件、目录名称有效性判断
1209         /// <summary>
1210         /// 判断目录名中字符是否合法
1211         /// </summary>
1212         /// <param name="DirectoryName">目录名称</param>
1213         public bool IsValidPathChars(string DirectoryName)
1214         {
1215             char[] invalidPathChars = Path.GetInvalidPathChars();
1216             char[] DirChar = DirectoryName.ToCharArray();
1217             foreach (char C in DirChar)
1218             {
1219                 if (Array.BinarySearch(invalidPathChars, C) >= 0)
1220                 {
1221                     return false;
1222                 }
1223             }
1224             return true;
1225         }
1226         /// <summary>
1227         /// 判断文件名中字符是否合法
1228         /// </summary>
1229         /// <param name="FileName">文件名称</param>
1230         public bool IsValidFileChars(string FileName)
1231         {
1232             char[] invalidFileChars = Path.GetInvalidFileNameChars();
1233             char[] NameChar = FileName.ToCharArray();
1234             foreach (char C in NameChar)
1235             {
1236                 if (Array.BinarySearch(invalidFileChars, C) >= 0)
1237                 {
1238                     return false;
1239                 }
1240             }
1241             return true;
1242         }
1243         #endregion
1244         #region 目录切换操作
1245         /// <summary>
1246         /// 进入一个目录
1247         /// </summary>
1248         /// <param name="DirectoryName">
1249         /// 新目录的名字。 
1250         /// 说明:如果新目录是当前目录的子目录,则直接指定子目录。如: SubDirectory1/SubDirectory2 ; 
1251         /// 如果新目录不是当前目录的子目录,则必须从根目录一级一级的指定。如: ./NewDirectory/SubDirectory1/SubDirectory2
1252         /// </param>
1253         public bool GotoDirectory(string DirectoryName)
1254         {
1255             string CurrentWorkPath = this.DirectoryPath;
1256             try
1257             {
1258                 DirectoryName = DirectoryName.Replace("\\", "/");
1259                 string[] DirectoryNames = DirectoryName.Split(new char[] { '/' });
1260                 if (DirectoryNames[0] == ".")
1261                 {
1262                     this.DirectoryPath = "/";
1263                     if (DirectoryNames.Length == 1)
1264                     {
1265                         return true;
1266                     }
1267                     Array.Clear(DirectoryNames, 0, 1);
1268                 }
1269                 bool Success = false;
1270                 foreach (string dir in DirectoryNames)
1271                 {
1272                     if (dir != null)
1273                     {
1274                         Success = EnterOneSubDirectory(dir);
1275                         if (!Success)
1276                         {
1277                             this.DirectoryPath = CurrentWorkPath;
1278                             return false;
1279                         }
1280                     }
1281                 }
1282                 return Success;
1283 
1284             }
1285             catch (Exception ep)
1286             {
1287                 this.DirectoryPath = CurrentWorkPath;
1288                 ErrorMsg = ep.ToString();
1289                 throw ep;
1290             }
1291         }
1292         /// <summary>
1293         /// 从当前工作目录进入一个子目录
1294         /// </summary>
1295         /// <param name="DirectoryName">子目录名称</param>
1296         private bool EnterOneSubDirectory(string DirectoryName)
1297         {
1298             try
1299             {
1300                 if (DirectoryName.IndexOf("/") >= 0 || !IsValidPathChars(DirectoryName))
1301                 {
1302                     throw new Exception("目录名非法!");
1303                 }
1304                 if (DirectoryName.Length > 0 && DirectoryExist(DirectoryName))
1305                 {
1306                     if (!DirectoryName.EndsWith("/"))
1307                     {
1308                         DirectoryName += "/";
1309                     }
1310                     _DirectoryPath += DirectoryName;
1311                     return true;
1312                 }
1313                 else
1314                 {
1315                     return false;
1316                 }
1317             }
1318             catch (Exception ep)
1319             {
1320                 ErrorMsg = ep.ToString();
1321                 throw ep;
1322             }
1323         }
1324         /// <summary>
1325         /// 从当前工作目录往上一级目录
1326         /// </summary>
1327         public bool ComeoutDirectory()
1328         {
1329             if (_DirectoryPath == "/")
1330             {
1331                 ErrorMsg = "当前目录已经是根目录!";
1332                 throw new Exception("当前目录已经是根目录!");
1333             }
1334             char[] sp = new char[1] { '/' };
1335 
1336             string[] strDir = _DirectoryPath.Split(sp, StringSplitOptions.RemoveEmptyEntries);
1337             if (strDir.Length == 1)
1338             {
1339                 _DirectoryPath = "/";
1340             }
1341             else
1342             {
1343                 _DirectoryPath = String.Join("/", strDir, 0, strDir.Length - 1);
1344             }
1345             return true;
1346 
1347         }
1348         #endregion
1349         #region 重载WebClient,支持FTP进度
1350         internal class MyWebClient : WebClient
1351         {
1352             protected override WebRequest GetWebRequest(Uri address)
1353             {
1354                 FtpWebRequest req = (FtpWebRequest) base.GetWebRequest(address);
1355                 req.UsePassive = false;
1356                 return req;
1357             }
1358         }
1359         #endregion
1360     }
1361 }
ClsFtp
调用方法,目前只用上传功能:
    定义全局私有变量:
 private clsFTP cf;
   按钮事件:
        private void btn_upFile_Click(object sender, EventArgs e)
        {
            lb_upload.Text = "正在上传文件,请等待...";
             cf = new clsFTP(new Uri("http://www.cnblogs.com/zhangjun1130/admin/ftp://192.168.43.55/"), "temp", "temp");
            string localFile = Application.StartupPath.ToString() + "http://www.cnblogs.com/zhangjun1130/admin/file://output//zt.rar";
             cf.UploadProgressChanged+=new clsFTP.De_UploadProgressChanged(cf_UploadProgressChanged);
             cf.UploadFileCompleted+=new clsFTP.De_UploadFileCompleted(cf_UploadFileCompleted);
             cf.UploadFileAsync(localFile, true);  //调用异步传输,若有文件存在则覆盖。
        }
   事件捆绑,反映上传进度:
        public void cf_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
        {
            this.pgrBarFileUpload.Maximum = (int)e.TotalBytesToSend;
            this.pgrBarFileUpload.Value =(int) e.BytesSent;
            lb_upload.Text = string.Format("文件总大小:{0}k,已经上传: {1}k。", e.TotalBytesToSend/1024,e.BytesSent/1024);
        }
        public void cf_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
        {
                        try
            {
                lb_upload.Text = "无法连接到服务器,或者用户登陆失败!";
                lb_error.Text =e.Error.Message.ToString();
            }
            catch
            {
                lb_upload.Text = "文件上传成功!";
                lb_error.Text = "";
            }
        }
例子


源文件地址:http://www.cnblogs.com/zhangjun1130/archive/2010/03/24/1693932.html

源文件地址下有详细说明,很详细,大牛!