lomg 发表于 2015-5-26 09:51:34

实现简单的FTP多线程下载和上传

  常想在园子里写点什么东西,但每当提笔,便已觉得肤浅,不敢写出来怡笑大方。对于各位战斗在软件第一线的道友们来说,本人只能算得上是一个业余选手,也许连业余也算不上。始终很自卑,觉得跟大家的水平相差太远。一直以来,对计算机都非常有兴趣,中专毕业以后,通过书籍和网上学了些皮毛。说来惭愧,中专三年,玩了三年游戏,严格地说,只能算是初中毕业。当年的愿望是希望能够从事软件相关的工作,无奈,学历低,专业也不对口。混迹于江湖N年,一直未能如愿。现在在一家工厂里从事管理工作,偶尔写点程序,协助管理。一转眼,毕业十多年了,光阴似箭哪。闲话扯多了,今天,鼓起勇气,写点东西,希望能够得到大家的指导。
  本想找一个相对完整的FTP实现的代码,集成到我工厂的ERP软件里,在网上找了很久,也没有合适的,只好自己动手做一个。以下界面只是测试界面,FTP的管理已经封装成单独的类,可以灵活调用。实现的界面如下图,使用WPF做界面,的确很方便,很灵活。接触WPF真有点相见恨晚的感觉。FTP服务器使用IIS架设,关于如何架设FTP服务器,网上有很多资料,相当简单,在此不多缀述。源码下载:http://files.iyunv.com/laoyang999/WpfApplication1.zip

  
  界面代码如下:



1
5   
6         
7            
8            
9            
10         
11         
12         
13            
14            
16            
17            
19            
20            
21            
22         
23         
24            
25            
26               
27               
28                     
29                     
30               
31               
32            
33         
34         
36            
37               
38                     
39                     
40               
41            
42            
43               
44                     
45                        
46                           
47                           
48                           
49                        
50                        
51                        
53                        
57                     
58               
59            
60         
61   
62
  
  首先,建立下FTP管理的类,以下这些代码是从网上Down下来的,有些东西,别人已经做好了现成的,就没必要重新写一遍了,多浪费时间啊。但是,从网上复制的这这段代码存在一些问题。第一,获取文件列表的时候,会把文件夹都一起显示出来;第二,上传和下载没有进度报告;对此,我做了一些修改。针对进度报告,采取了事件触发的方式。对于获取文件列表(不包含文件夹),在网上找了N多代码,似乎都有问题。后来,我用了一个取巧的办法,用WebRequestMethods.Ftp.ListDirectoryDetails 的方法,获取目录明细,明细中包含的就是文件夹了,把文件夹提取出来,再跟获取的文件列表进行比对,名字相同的,就剔除。
  以下是FTP管理类


View Code


1 //FTP操作
2
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Text;
7 using System.IO;
8 using System.Net;
9
10 namespace WpfApplication1
11 {
12    public class FTPHelper
13   {
14
15         //下载进度变化
16         public delegate void OnDonwnLoadProcessHandle(object sender);
17      //上传进度变化
18      public delegate void OnUpLoadProcessHandle(object sender);
19
20      public event OnDonwnLoadProcessHandle OnDownLoadProgressChanged;
21      public event OnUpLoadProcessHandle OnUpLoadProgressChanged;
22
23      string ftpServerIP;
24      string ftpRemotePath;
25      string ftpUserID;
26      string ftpPassword;
27      string ftpURI;
28      int dowLoadComplete; //为图方便,上传和下载都用这个数据
29      bool DownLoadCancel;
30      bool _UPLoadCancel;
31      int upLoadComplete;
32
33      //下载进度
34      public int DownComplete
35      {
36            get { return dowLoadComplete; }
37      }
38      //上传进度
39      public int UpLoadComplete
40      {
41            get { return upLoadComplete; }
42      }
43
44       //取消状态
45
46      public boolDownLoadCancelStatus
47      {
48            get { return DownLoadCancel; }
49      }
50      //取消上传状态
51      public bool UpLoadCancel
52      {
53            get { return _UPLoadCancel; }
54      }
55      ///
56      /// 初始化
57      ///
58      ///
59      ///
60      ///
61      ///
62      public FTPHelper(string server, string remotePath, string userID, string password)
63      {
64            ftpServerIP = server;
65            ftpRemotePath = remotePath;
66            ftpUserID = userID;
67            ftpPassword = password;
68            ftpURI = "ftp://" + ftpServerIP + "/" + remotePath ;
69            dowLoadComplete = 0;
70            DownLoadCancel = false;//下载操作是否取消
71            _UPLoadCancel = false;//上传是否取消
72      }
73
74      //上传文件
75      public string UploadFile(string[] filePaths)
76      {
77            StringBuilder sb = new StringBuilder();
78            if (filePaths != null && filePaths.Length > 0)
79            {
80                foreach (var file in filePaths)
81                {
82                  sb.Append(Upload(file));
83
84                }
85            }
86            return sb.ToString();
87      }
88
89      ///
90      /// 上传文件
91      ///
92      ///
93       public string Upload(string filename)
94      {
95            FileInfo fileInf = new FileInfo(filename);
96            
97            if (!fileInf.Exists)
98            {
99                return filename + " 不存在!\n";
100            }
101            
102            long fileSize = fileInf.Length;//获取本地文件的大小
103
104            string uri = ftpURI + fileInf.Name;
105            FtpWebRequest reqFTP;
106            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
107
108            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
109            reqFTP.KeepAlive = false;
110            reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
111            reqFTP.UseBinary = true;
112            reqFTP.UsePassive = false;//选择主动还是被动模式
113            //Entering Passive Mode
114            reqFTP.ContentLength = fileInf.Length;
115            int buffLength = 2048;
116            byte[] buff = new byte;
117            int contentLen;
118            FileStream fs = fileInf.OpenRead();
119            try
120            {
121                Stream strm = reqFTP.GetRequestStream();
122                contentLen = fs.Read(buff, 0, buffLength);
123                long hasUpLoad = contentLen;
124                while (contentLen != 0)
125                {
126                  strm.Write(buff, 0, contentLen);
127                  contentLen = fs.Read(buff, 0, buffLength);
128                  hasUpLoad += contentLen;
129                  upLoadComplete= (int)((Single)hasUpLoad / (Single)fileSize * 100.0);
130                  if (this.OnUpLoadProgressChanged != null)
131                  {
132                        OnUpLoadProgressChanged(this);
133                  }
134                  if (this.UpLoadCancel == true) //是否已经取消上传
135                  {
136                        strm.Close();
137                        fs.Close();
138                        if (FileExist(fileInf.Name))//删除服务器中已经存在的文件
139                        { Delete(fileInf.Name); }
140                        return "";
141                  }
142                }
143                strm.Close();
144                fs.Close();
145            }
146            catch
147            {
148                return "同步 " + filename + "时连接不上服务器!\n";
149            }
150            return "";
151      }
152
153      ///
154      /// 下载
155      ///
156      ///
157      ///
158      public void Download(string filePath, string fileName)
159      {
160            FtpWebRequest reqFTP;
161            try
162            {
163                FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
164
165                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + fileName));
166                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
167                reqFTP.UseBinary = true;
168                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
169                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
170                Stream ftpStream = response.GetResponseStream();
171                long cl = response.ContentLength;
172                int bufferSize = 2048;
173                int readCount;
174                byte[] buffer = new byte;
175
176                readCount = ftpStream.Read(buffer, 0, bufferSize);
177                //获取文件大小
178                long fileLength = GetFileSize(fileName);
179                long hasDonwnload = (long)readCount;
180
181                while (readCount > 0)
182                {
183                  outputStream.Write(buffer, 0, readCount);
184                  readCount = ftpStream.Read(buffer, 0, bufferSize);
185                  hasDonwnload += (long)readCount;
186                  //获取下载进度
187                  this.dowLoadComplete = (int)((Single)hasDonwnload / (Single)fileLength * 100.0);
188                  if (OnDownLoadProgressChanged != null)
189                  {
190                        OnDownLoadProgressChanged(this);//触发事件,用于客户端获取下载进度
191                  }
192                  if (DownLoadCancel == true)
193                  {
194                        ftpStream.Close();
195                        outputStream.Close();
196                        response.Close();
197                        //删除文件
198                        if (File.Exists(filePath + "\\" + fileName))
199                        {
200                            File.Delete(filePath + "\\" + fileName);
201                        }
202                        return;//退出程序
203                  }
204                }
205
206                ftpStream.Close();
207                outputStream.Close();
208                response.Close();
209            }
210            catch (Exception ex)
211            {
212                throw new Exception(ex.Message);
213            }
214      }
215
216      //取消下载
217      public void CancelDownLoad()
218      {
219            this.DownLoadCancel = true;
220      }
221
222      //取消上传
223      public void CancelUpLoad()
224      {
225            this._UPLoadCancel = true;
226      }
227      ///
228      /// 删除文件
229      ///
230      ///
231      public void Delete(string fileName)
232      {
233            try
234            {
235                string uri = ftpURI + fileName;
236                FtpWebRequest reqFTP;
237                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
238
239                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
240                reqFTP.KeepAlive = false;
241                reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
242
243                string result = String.Empty;
244                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
245                long size = response.ContentLength;
246                Stream datastream = response.GetResponseStream();
247                StreamReader sr = new StreamReader(datastream);
248                result = sr.ReadToEnd();
249                sr.Close();
250                datastream.Close();
251                response.Close();
252            }
253            catch (Exception ex)
254            {
255                throw new Exception(ex.Message);
256            }
257      }
258
259      ///
260      /// 获取当前目录下明细(包含文件和文件夹)
261      ///
262      ///
263      public string[] GetFilesDetailList()
264      {
265            try
266            {
267                StringBuilder result = new StringBuilder();
268                FtpWebRequest ftp;
269                ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI));
270                ftp.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
271                ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
272                WebResponse response = ftp.GetResponse();
273                StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312"));
274                string line = reader.ReadLine();
275                line = reader.ReadLine();
276                line = reader.ReadLine();
277                while (line != null)
278                {
279                  result.Append(line);
280                  result.Append("\n");
281                  line = reader.ReadLine();
282                }
283                result.Remove(result.ToString().LastIndexOf("\n"), 1);
284                reader.Close();
285                response.Close();
286                return result.ToString().Split('\n');
287            }
288            catch (Exception ex)
289            {
290                throw new Exception(ex.Message);
291            }
292      }
293
294      ///
295      /// 获取当前目录下文件列表(仅文件)
296      ///
297      ///
298      public List GetFileList(string mask)
299      {
300            StringBuilder result = new StringBuilder();
301            FtpWebRequest reqFTP;
302            try
303            {
304                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI));
305                reqFTP.UseBinary = true;
306                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
307                reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
308                WebResponse response = reqFTP.GetResponse();
309                StreamReader reader = new StreamReader(response.GetResponseStream(),System.Text.Encoding.GetEncoding("gb2312"));
310               
311                string line = reader.ReadLine();
312                while (line != null)
313                {
314                  if (mask.Trim() != string.Empty && mask.Trim() != "*.*")
315                  {
316                        string mask_ = mask.Substring(0, mask.IndexOf("*"));
317                        if (line.Substring(0, mask_.Length) == mask_)
318                        {
319                              result.Append(line);
320                              result.Append("\n");
321                        }
322                  }
323                  else
324                  {
325                            result.Append(line);
326                            result.Append("\n");
327                  }
328                  
329                  line = reader.ReadLine();
330                }
331                result.Remove(result.ToString().LastIndexOf('\n'), 1);
332                reader.Close();
333                response.Close();
334               
335               string[] files= result.ToString().Split('\n');
336               string[] Directors = GetDirectoryList();
337               List tempList = new List();
338               for (int i = 0; i < files.Length; i++)
339               {
340                   bool isFile = true;
341                   for (int j = 0; j < Directors.Length; j++)
342                   {
343                     if (files.Trim() == Directors.Trim())
344                     { isFile = false; }
345                   }
346                   if (isFile == true)
347                   {
348                     tempList.Add(files);
349                   }
350               }
351               return tempList;
352            }
353            catch (Exception ex)
354            {
355                if (ex.Message.Trim() != "远程服务器返回错误: (550) 文件不可用(例如,未找到文件,无法访问文件)。")
356                {
357                  throw new Exception(ex.Message);
358                }
359                throw new Exception("获取文件列表出错,错误:" + ex.Message);
360            }
361      }
362
363      ///
364      /// 获取当前目录下所有的文件夹列表(仅文件夹)
365      ///
366      ///
367      public string[] GetDirectoryList()
368      {
369            string[] drectory = GetFilesDetailList();
370            string m = string.Empty;
371            foreach (string str in drectory)
372            {
373                if (str.Contains(""))
374                {
375                  m += str.Substring(39).Trim() + "\n";
376                }
377            }
378            m = m.Substring(0, m.Length - 1);
379            return m.Split('\n');
380      }
381      
382      ///
383      /// 判断当前目录下指定的子目录是否存在
384      ///
385      /// 指定的目录名
386      public bool DirectoryExist(string RemoteDirectoryName)
387      {
388            string[] dirList = GetDirectoryList();
389            foreach (string str in dirList)
390            {
391                if (str.Trim() == RemoteDirectoryName.Trim())
392                {
393                  return true;
394                }
395            }
396            return false;
397      }
398
399      ///
400      /// 判断当前目录下指定的文件是否存在
401      ///
402      /// 远程文件名
403      public bool FileExist(string RemoteFileName)
404      {
405            List fileList = GetFileList("*.*");
406            foreach (string str in fileList)
407            {
408                if (str.Trim() == RemoteFileName.Trim())
409                {
410                  return true;
411                }
412            }
413            return false;
414      }
415
416      ///
417      /// 创建文件夹
418      ///
419      ///
420      public void MakeDir(string dirName)
421      {
422            FtpWebRequest reqFTP;
423            try
424            {
425                // dirName = name of the directory to create.
426                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + dirName));
427                reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
428                reqFTP.UseBinary = true;
429                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
430                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
431                Stream ftpStream = response.GetResponseStream();
432
433                ftpStream.Close();
434                response.Close();
435            }
436            catch (Exception ex)
437            {
438                throw new Exception(ex.Message);
439            }
440      }
441
442      ///
443      /// 获取指定文件大小
444      ///
445      ///
446      ///
447      public long GetFileSize(string filename)
448      {
449            FtpWebRequest reqFTP;
450            long fileSize = 0;
451            try
452            {
453                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + filename));
454                reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
455                reqFTP.UseBinary = true;
456                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
457                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
458                Stream ftpStream = response.GetResponseStream();
459                fileSize = response.ContentLength;
460
461                ftpStream.Close();
462                response.Close();
463            }
464            catch (Exception ex)
465            {
466                throw new Exception(ex.Message);
467            }
468            return fileSize;
469      }
470
471      ///
472      /// 改名
473      ///
474      ///
475      ///
476      public void ReName(string currentFilename, string newFilename)
477      {
478            FtpWebRequest reqFTP;
479            try
480            {
481                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + currentFilename));
482                reqFTP.Method = WebRequestMethods.Ftp.Rename;
483                reqFTP.RenameTo = newFilename;
484                reqFTP.UseBinary = true;
485                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
486                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
487                Stream ftpStream = response.GetResponseStream();
488
489                ftpStream.Close();
490                response.Close();
491            }
492            catch (Exception ex)
493            {
494                throw new Exception( ex.Message);
495            }
496      }
497
498      ///
499      /// 移动文件
500      ///
501      ///
502      ///
503      public void MovieFile(string currentFilename, string newDirectory)
504      {
505            ReName(currentFilename, newDirectory);
506      }
507   }
508 }
  以下是文件信息类(fileinfo),用于各类之间传递。UI上面的数据与fileinfo绑定。在写这个类的时候,我比较偷懒,上传或是下载的更新状态我都放到了fileinfo的DownLoadStatus属性里了,为于避免有道友看不明白,特此说明。
  文件信息类:


View Code


1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.ComponentModel;
6
7 namespace WpfApplication1
8 {
9    public class fileInfo:INotifyPropertyChanged
10   {
11      public fileInfo()
12      {
13            complete = 0;
14      }
15
16      //文件名
17      public string fileName { get; set; }
18       //完成进度
19      int _complete;
20      public int complete
21      {
22            get { return _complete; }
23            set
24            {
25                _complete = value;
26                OnPropertyChanged("complete");
27            }
28      }
29
30      //下载状态
31      string downloadStatus;
32      public string DownLoadStatus
33      {
34            get { return downloadStatus; }
35            set
36            {
37                downloadStatus = value;
38                OnPropertyChanged("DownLoadStatus");
39            }
40      }
41
42      //本地路径
43      public string LocalPath
44      { get; set; }
45      
46      public event PropertyChangedEventHandler PropertyChanged;
47
48      private void OnPropertyChanged(string propertyName)
49      {
50            if (PropertyChanged != null)
51            {
52                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
53            }
54      }
55   }
56 }
  为了进行多线程处理,我封装一个线程信息类,当要取消某个文件下载的时候,可以方便得定位到线程。在这里,我没有采取线程堵塞的方法结束线程,而是在FTP管理类(FTPHelper)里添加了两个标志



      //下载取消状态
public boolDownLoadCancelStatus
{
get { return DownLoadCancel; }
}
//取消上传状态
public bool UpLoadCancel
{
get { return _UPLoadCancel; }
}
  以上两个属性,用于标识是否取消下载或是上传,以上标记为true时,下载或是上传的操作过程即中止,同时触发事件。
  线程信息类(DownLoadProcess),命名不太规范,这个类也用于上传文件。
  代码如下:


View Code


1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
6
7 namespace WpfApplication1
8 {
9    public class DownLoadProcess
10   {
11
12      public delegate void DownloadStatusChangeHandle(object sender);
13      public event DownloadStatusChangeHandle OnDownloadStatusChanged;
14
15      public event DownloadStatusChangeHandle OnUpLoadComplete;//上传完成
16
17      FTPHelper FTP;
18      fileInfo file;
19      string Path;
20      Thread downloadThread;
21      Thread uploadThread;
22
23      #region Properties
24      public string DownLoadStatus
25      { get; set; }
26
27      public fileInfo downloadFile
28      {
29            get { return file; }
30            set { file = value; }
31      }
32
33      #endregion
34      
35      public DownLoadProcess(FTPHelper f, fileInfo fi,string path)
36      {
37            FTP = f;
38            file = fi;
39            Path = path;
40            FTP.OnDownLoadProgressChanged += new FTPHelper.OnDonwnLoadProcessHandle(FTP_OnDownLoadProgressChanged);//下载
41            FTP.OnUpLoadProgressChanged += new FTPHelper.OnUpLoadProcessHandle(FTP_OnUpLoadProgressChanged);//上传
42      }
43
44      //上传进度
45      void FTP_OnUpLoadProgressChanged(object sender)
46      {
47            FTPHelper ftp = sender as FTPHelper;
48            file.complete = ftp.UpLoadComplete;
49      }
50
51      //下载进度
52      void FTP_OnDownLoadProgressChanged(object sender)
53      {
54            FTPHelper ftp = sender as FTPHelper;
55            file.complete = ftp.DownComplete;
56      }
57
58      //用于线程调用
59      private void ThreadProc()
60      {
61            FTP.Download(Path, file.fileName);
62            if (this.OnDownloadStatusChanged != null&&FTP.DownLoadCancelStatus!=true)
63            {
64                this.DownLoadStatus = "Finished";
65                OnDownloadStatusChanged(this);
66            }
67      }
68
69      //用于线程调用开始上传
70      private void ThreadUpLoad()
71      {
72            this.file.DownLoadStatus = "上传中...";
73            FTP.Upload(file.LocalPath);
74            if (FTP.UpLoadCancel != true)
75            { this.file.DownLoadStatus = "完成"; }
76            else
77            { this.file.DownLoadStatus = "已取消"; }
78            Thread.Sleep(300);
79            if (this.OnUpLoadComplete != null)
80            {
81                OnUpLoadComplete(this);
82            }
83      }
84
85      //开始下载
86      public void StartDownLoad()
87      {
88            downloadThread = new Thread(new ThreadStart(this.ThreadProc));
89            downloadThread.Start();
90            this.file.DownLoadStatus = "取消";
91      }
92
93      //开始上传
94      public void StartUpLoad()
95      {
96            uploadThread = new Thread(new ThreadStart(this.ThreadUpLoad));
97            uploadThread.Start();
98      }
99      //取消上传
100      public void StopUpLoad()
101      {
102            if (FTP != null)
103            {
104                FTP.CancelUpLoad();
105            }
106      }
107
108      //取消下载
109      public void StopDownload()
110      {
111            if (FTP != null)
112            {
113                FTP.CancelDownLoad();
114               
115                if (OnDownloadStatusChanged != null)
116                {
117                  this.DownLoadStatus = "Canceled";
118                  OnDownloadStatusChanged(this);
119                }
120            }
121      }
122   }
123 }
  最后,把界面后台代码贴上来:


View Code


1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Data;
8 using System.Windows.Documents;
9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Navigation;
13 using System.Windows.Shapes;
14 using System.Windows.Forms;
15 using System.Collections.ObjectModel;
16 using System.Threading;
17 using Microsoft.Win32;
18 using System.IO;
19
20 namespace WpfApplication1
21 {
22
23   ///
24   /// MainWindow.xaml 的交互逻辑
25   ///
26   public partial class MainWindow : Window
27   {
28
29         ObservableCollection files = new ObservableCollection();
30         List OnDownLoadList = new List();
31
32         public MainWindow()
33         {
34             InitializeComponent();
35
36             this.fileList.ItemsSource = files;
37         }
38
39         private void Connect_click(object sender, System.Windows.RoutedEventArgs e)
40         {
41             // 在此处添加事件处理程序实现。
42             FTPHelper FTP;
43             FTP = new FTPHelper(this.serverIP.Text, "", this.userID.Text, this.pwd.Password);
44             GetFiles(FTP);
45
46         }
47
48         //获取文件列表
49         private void GetFiles(FTPHelper FTP)
50         {
51             if (FTP != null)
52             {
53                List strFiles = FTP.GetFileList("*");
54                files.Clear();
55               for (int i = 0; i < strFiles.Count; i++)
56               {
57                     fileInfo f = new fileInfo();
58                     f.fileName = strFiles;
59                     f.DownLoadStatus = "下载";
60                     files.Add(f);
61               }
62             }
63         }
64
65
66         private void btn_Click(object sender, RoutedEventArgs e)
67         {
68            
69             System.Windows.Controls.Button btn = sender as System.Windows.Controls.Button;
70             fileInfo file = btn.Tag as fileInfo;
71
72             if (file.DownLoadStatus== "下载"||file.DownLoadStatus== "完成")
73             {
74               if (file.DownLoadStatus=="完成")
75               {
76                     if (System.Windows.MessageBox.Show("该文件已经下载,是否继续下载?",
77                     "提示", MessageBoxButton.YesNo) == MessageBoxResult.No)
78                         return;
79               }
80             string path;
81             FolderBrowserDialog dia = new FolderBrowserDialog();
82             DialogResult result = dia.ShowDialog();
83             if (result == System.Windows.Forms.DialogResult.Cancel)
84             { return; }
85             path = dia.SelectedPath;
86   
87             FTPHelper FTP;
88             FTP = new FTPHelper(this.serverIP.Text, "", this.userID.Text, this.pwd.Password);
89             DownLoadProcess dp = new DownLoadProcess(FTP, file, path);
90             this.OnDownLoadList.Add(dp);
91             dp.StartDownLoad();//开始下载
92             dp.OnDownloadStatusChanged += new DownLoadProcess.DownloadStatusChangeHandle(dp_OnDownloadStatusChanged);
93
94             }
95               //取消下载
96             else
97             {
98               foreach (DownLoadProcess d in OnDownLoadList)
99               {
100                     if (d.downloadFile == file)
101                     {
102                         d.StopDownload();
103                         OnDownLoadList.Remove(d);
104                         System.Windows.MessageBox.Show("已取消");
105                         break;
106                     }
107               }
108             }
109            
110            
111         }
112
113         //下载状态发生变化
114         void dp_OnDownloadStatusChanged(object sender)
115         {
116             DownLoadProcess dp = sender as DownLoadProcess;
117
118             if (dp.DownLoadStatus == "Canceled")
119             {
120               dp.downloadFile.complete = 0;
121               dp.downloadFile.DownLoadStatus = "下载";
122             }
123             else if(dp.DownLoadStatus=="Finished")
124             {
125               dp.downloadFile.DownLoadStatus = "完成";
126             }
127         }
128
129         //上传文件
130         DownLoadProcess upPro;
131         private void btn_UpLoad(object sender, System.Windows.RoutedEventArgs e)
132         {
133             // 在此处添加事件处理程序实现。
134             if (btnUpload.Content.ToString() == "上传")
135             {
136               btnUpload.Content = "取消";
137               string filename;
138               System.Windows.Forms.OpenFileDialog opd = new System.Windows.Forms.OpenFileDialog();
139               DialogResult result = opd.ShowDialog();
140               if (result == System.Windows.Forms.DialogResult.OK)
141               {
142                     filename = opd.FileName;
143                     FileInfo fileInf = new FileInfo(filename);
144                     fileInfo file = new fileInfo();
145                     file.LocalPath = filename;
146                     file.complete = 0;
147                     file.fileName = fileInf.Name;
148                     gdUpLoad.DataContext = file;
149                     FTPHelper FTP;
150                     FTP = new FTPHelper(this.serverIP.Text, "", this.userID.Text, this.pwd.Password);
151                     upPro = new DownLoadProcess(FTP, file, "");
152                     upPro.OnUpLoadComplete += new DownLoadProcess.DownloadStatusChangeHandle(upPro_OnUpLoadComplete);
153                     upPro.StartUpLoad();
154                     filePanel.Visibility = System.Windows.Visibility.Visible;
155               }
156             }
157             else
158             {
159               if (this.upPro != null)
160               { upPro.StopUpLoad(); }
161             }
162         }
163
164         //上传完成
165         void upPro_OnUpLoadComplete(object sender)
166         {
167             UploadCompleteHandle del = new UploadCompleteHandle(UpLoadComplete);
168             this.Dispatcher.BeginInvoke(del); //使用分发器
169         }
170
171         private delegate void UploadCompleteHandle();
172         private void UpLoadComplete()
173         {
174             this.btnUpload.Content = "上传";
175             this.filePanel.Visibility = System.Windows.Visibility.Hidden;
176             //把数据源清空
177             gdUpLoad.DataContext = null;
178             FTPHelper FTP;
179             FTP = new FTPHelper(this.serverIP.Text, "", this.userID.Text, this.pwd.Password);
180             GetFiles(FTP);
181         }
182
183         //窗体关闭前,把所有执行中的任务关闭
184         private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
185         {
186             //关闭正在下载中的任务
187             foreach (DownLoadProcess p in OnDownLoadList)
188             {
189            
190             }
191         }
192   }
193   
194 }
  下载管理,我用了一个List进于管理 ,上传的时候,只用了一个线程信息类,还是我比较懒,有些东西,觉得够用就行了,必竟给我工厂里用,已经足够了。至于其他道友要修改的话,也是非常简单的。
    使用的开发平台,我用的是VS2010,写代码挺好,就是从界面到代码切换的时候总是会卡住,到网上查了一下,说是VS本身的问题,VS2008倒是没问题,但是没有DataGRid控件,很不爽。所以,我写前台用Blend,后台用VS2010,还好,都是微软件的产品,无缝连接。
页: [1]
查看完整版本: 实现简单的FTP多线程下载和上传