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

    常想在园子里写点什么东西,但每当提笔,便已觉得肤浅,不敢写出来怡笑大方。对于各位战斗在软件第一线的道友们来说,本人只能算得上是一个业余选手,也许连业余也算不上。始终很自卑,觉得跟大家的水平相差太远。一直以来,对计算机都非常有兴趣,中专毕业以后,通过书籍和网上学了些皮毛。说来惭愧,中专三年,玩了三年游戏,严格地说,只能算是初中毕业。当年的愿望是希望能够从事软件相关的工作,无奈,学历低,专业也不对口。混迹于江湖N年,一直未能如愿。现在在一家工厂里从事管理工作,偶尔写点程序,协助管理。一转眼,毕业十多年了,光阴似箭哪。闲话扯多了,今天,鼓起勇气,写点东西,希望能够得到大家的指导。

  本想找一个相对完整的FTP实现的代码,集成到我工厂的ERP软件里,在网上找了很久,也没有合适的,只好自己动手做一个。以下界面只是测试界面,FTP的管理已经封装成单独的类,可以灵活调用。实现的界面如下图,使用WPF做界面,的确很方便,很灵活。接触WPF真有点相见恨晚的感觉。FTP服务器使用IIS架设,关于如何架设FTP服务器,网上有很多资料,相当简单,在此不多缀述。源码下载:https://files.cnblogs.com/laoyang999/WpfApplication1.zip

 

 界面代码如下:

 1 <Window x:Class="WpfApplication1.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525" Closing="Window_Closing">
 5     <Grid>
 6         <Grid.RowDefinitions>
 7             <RowDefinition Height="30"/>
 8             <RowDefinition Height="30"/>
 9             <RowDefinition/>
10         </Grid.RowDefinitions>
11         
12         <StackPanel Orientation="Horizontal" Grid.Row="0" >
13             <TextBlock Text="ServerIP:" Margin="3" VerticalAlignment="Center"/>
14             <TextBox x:Name="serverIP" Text="192.168.1.100" VerticalAlignment="Center"
15             Width="100"/>
16             <TextBlock Text="UserID:" Margin="3" VerticalAlignment="Center"/>
17             <TextBox x:Name="userID" Text="administrator" VerticalAlignment="Center"
18             Width="80"/>
19             <TextBlock Text="Password:" Margin="3" VerticalAlignment="Center"/>
20             <PasswordBox x:Name="pwd" Password="123456" Width="65" Margin="3"  VerticalAlignment="Center"/>
21             <Button x:Name="btnConnect" Margin="3" Content="连接" VerticalAlignment="Center" Click="Connect_click" />
22         </StackPanel>
23         <Grid Grid.Row="1" x:Name="gdUpLoad">
24             <Border BorderBrush="Gray" BorderThickness="0,1,0,0" Margin="3,0,3,0"/>
25             <StackPanel Orientation="Horizontal">
26                 <Button x:Name="btnUpload" Content="上传" Width="50" Margin="5,4,2,4" Tag="{Binding }" Click="btn_UpLoad"/>
27                 <StackPanel x:Name="filePanel" Visibility="Hidden">
28                     <TextBlock Text="{Binding fileName}" Margin="2"/>
29                     <ProgressBar Maximum="100" Height="8" Value="{Binding complete}"/>
30                 </StackPanel>
31                 <TextBlock Text="{Binding DownLoadStatus}" Margin="3" VerticalAlignment="Center" Foreground="Blue"/>
32             </StackPanel>
33         </Grid>
34         <ListBox Grid.Row="2"  x:Name="fileList" 
35         Margin="3" BorderBrush="Black" BorderThickness="1">
36             <ListBox.Background>
37                 <LinearGradientBrush EndPoint="0.497,0.907" StartPoint="0.5,0">
38                     <GradientStop Color="#FFE5DF9E" Offset="0"/>
39                     <GradientStop Color="#FFFEFFF9" Offset="1"/>
40                 </LinearGradientBrush>
41             </ListBox.Background>
42             <ListBox.ItemTemplate>
43                 <DataTemplate>
44                     <Grid>
45                         <Grid.ColumnDefinitions>
46                             <ColumnDefinition Width="200"/>
47                             <ColumnDefinition MinWidth="80"/>
48                             <ColumnDefinition MinWidth="50"/>
49                         </Grid.ColumnDefinitions>
50                         <TextBlock Text="{Binding fileName}" Grid.Column="0"/>
51                         <ProgressBar Grid.Column="1" Margin="2" Height="10" Maximum="100" VerticalAlignment="Center"
52                         Value="{Binding complete}"/>
53                         <Button x:Name="btn" Grid.Column="2" Content="{Binding DownLoadStatus}"
54                          Margin="2,0,2,0" VerticalAlignment="Center" Height="20"
55                          Tag="{Binding }"
56                           Click="btn_Click"/>
57                     </Grid>
58                 </DataTemplate>
59             </ListBox.ItemTemplate>
60         </ListBox>
61     </Grid>
62 </Window>

 

   首先,建立下FTP管理的类,以下这些代码是从网上Down下来的,有些东西,别人已经做好了现成的,就没必要重新写一遍了,多浪费时间啊。但是,从网上复制的这这段代码存在一些问题。第一,获取文件列表的时候,会把文件夹都一起显示出来;第二,上传和下载没有进度报告;对此,我做了一些修改。针对进度报告,采取了事件触发的方式。对于获取文件列表(不包含文件夹),在网上找了N多代码,似乎都有问题。后来,我用了一个取巧的办法,用WebRequestMethods.Ftp.ListDirectoryDetails 的方法,获取目录明细,明细中包含<DIR>的就是文件夹了,把文件夹提取出来,再跟获取的文件列表进行比对,名字相同的,就剔除。

以下是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 bool  DownLoadCancelStatus
 47        {
 48            get { return DownLoadCancel; }
 49        }
 50        //取消上传状态
 51        public bool UpLoadCancel
 52        {
 53            get { return _UPLoadCancel; }
 54        }
 55        /// <summary>
 56        /// 初始化
 57        /// </summary>
 58        /// <param name="server"></param>
 59        /// <param name="remotePath"></param>
 60        /// <param name="userID"></param>
 61        /// <param name="password"></param>
 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        /// <summary>
 90        /// 上传文件
 91        /// </summary>
 92        /// <param name="filename"></param>
 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[buffLength];
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        /// <summary>
154        /// 下载
155        /// </summary>
156        /// <param name="filePath"></param>
157        /// <param name="fileName"></param>
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[bufferSize];
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        /// <summary>
228        /// 删除文件
229        /// </summary>
230        /// <param name="fileName"></param>
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        /// <summary>
260        /// 获取当前目录下明细(包含文件和文件夹)
261        /// </summary>
262        /// <returns></returns>
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        /// <summary>
295        /// 获取当前目录下文件列表(仅文件)
296        /// </summary>
297        /// <returns></returns>
298        public List<string> 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<string> tempList = new List<string>();
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[i].Trim() == Directors[j].Trim())
344                       { isFile = false; }
345                   }
346                   if (isFile == true)
347                   {
348                       tempList.Add(files[i]);
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        /// <summary>
364        /// 获取当前目录下所有的文件夹列表(仅文件夹)
365        /// </summary>
366        /// <returns></returns>
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("<DIR>"))
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        /// <summary>
383        /// 判断当前目录下指定的子目录是否存在
384        /// </summary>
385        /// <param name="RemoteDirectoryName">指定的目录名</param>
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        /// <summary>
400        /// 判断当前目录下指定的文件是否存在
401        /// </summary>
402        /// <param name="RemoteFileName">远程文件名</param>
403        public bool FileExist(string RemoteFileName)
404        {
405            List<string> 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        /// <summary>
417        /// 创建文件夹
418        /// </summary>
419        /// <param name="dirName"></param>
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        /// <summary>
443        /// 获取指定文件大小
444        /// </summary>
445        /// <param name="filename"></param>
446        /// <returns></returns>
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        /// <summary>
472        /// 改名
473        /// </summary>
474        /// <param name="currentFilename"></param>
475        /// <param name="newFilename"></param>
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        /// <summary>
499        /// 移动文件
500        /// </summary>
501        /// <param name="currentFilename"></param>
502        /// <param name="newFilename"></param>
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 bool  DownLoadCancelStatus
       {
           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     /// <summary>
 24     /// MainWindow.xaml 的交互逻辑
 25     /// </summary>
 26     public partial class MainWindow : Window
 27     {
 28 
 29         ObservableCollection<fileInfo> files = new ObservableCollection<fileInfo>();
 30         List<DownLoadProcess> OnDownLoadList = new List<DownLoadProcess>();
 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<string> 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[i];
 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,还好,都是微软件的产品,无缝连接。

posted on 2012-11-19 21:53  老杨999  阅读(6902)  评论(1编辑  收藏  举报

导航