實現簡單的FTP多線程下載和上傳


    常想在園子里寫點什么東西,但每當提筆,便已覺得膚淺,不敢寫出來怡笑大方。對於各位戰斗在軟件第一線的道友們來說,本人只能算得上是一個業余選手,也許連業余也算不上。始終很自卑,覺得跟大家的水平相差太遠。一直以來,對計算機都非常有興趣,中專畢業以后,通過書籍和網上學了些皮毛。說來慚愧,中專三年,玩了三年游戲,嚴格地說,只能算是初中畢業。當年的願望是希望能夠從事軟件相關的工作,無奈,學歷低,專業也不對口。混跡於江湖N年,一直未能如願。現在在一家工廠里從事管理工作,偶爾寫點程序,協助管理。一轉眼,畢業十多年了,光陰似箭哪。閑話扯多了,今天,鼓起勇氣,寫點東西,希望能夠得到大家的指導。

  本想找一個相對完整的FTP實現的代碼,集成到我工廠的ERP軟件里,在網上找了很久,也沒有合適的,只好自己動手做一個。以下界面只是測試界面,FTP的管理已經封裝成單獨的類,可以靈活調用。實現的界面如下圖,使用WPF做界面,的確很方便,很靈活。接觸WPF真有點相見恨晚的感覺。FTP服務器使用IIS架設,關於如何架設FTP服務器,網上有很多資料,相當簡單,在此不多綴述。源碼下載:http://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,還好,都是微軟件的產品,無縫連接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM