FTP上传下载类封装
View Code1using 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]