猫猫1 发表于 2015-5-30 01:54:07

FTP上传下载类封装

View Code


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