2009年12月1日 星期二

C#實現FTP下載代碼(含續傳與進度列)

最近在學習C#程式語言
於是乎模仿了網路上的範例
依樣畫葫蘆寫個FTP的下載代碼(含續傳、進度顯示)
private void Download(string filePath, string fileName)
{
    FtpWebRequest ftpReq;
    //宣告FTP連線
    ftpReq = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + IpAdd + "/" + fileName));
    //取得欲下載檔案的大小(位元)存至 fiesize
    ftpReq.Method = WebRequestMethods.Ftp.GetFileSize;
    //認證
    ftpReq.Credentials = new NetworkCredential(UName, UPWord);
    int filesize = (int)ftpReq.GetResponse().ContentLength;
    
    //宣告FTP連線
    ftpReq = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + IpAdd + "/" + fileName));
    //下載
    ftpReq.Method = WebRequestMethods.Ftp.DownloadFile;
    //認證
    ftpReq.Credentials = new NetworkCredential(UName, UPWord);

    //binaary
    ftpReq.UseBinary = true;

    //進度列初始化
    progressBar1.Value = 0;
    progressBar1.Maximum = filesize;
    lbProgress.Text = "0/" + filesize.ToString();

    //支援續傳
    FileInfo fi = new FileInfo(filePath + "\\" + fileName);
    FileStream fs = null;
    //檢測是否已有相同檔名的存在於client端
    if (fi.Exists)
    {
        //若存在,由中斷點繼續傳輸
        ftpReq.ContentOffset = fi.Length;
        //.apend 檔案存在時開啟檔案至末端 or 建立新檔
        fs = new FileStream(filePath + "\\" + fileName, FileMode.Append);
    }
    else //client端無檔案 則重新建立新檔
        fs = new FileStream(filePath + "\\" + fileName, FileMode.Create);
    //建立ftp連線
    FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse();
    
    bool bfinish = false;                
    try
    {
        //取得下載用的stream物件
        //ftpResp.GetResponseStream()--->擷取包含從FTP server傳送之回應資料的資料流
        using (Stream stm = ftpResp.GetResponseStream())
        {
            //以block方式多批寫入
            byte[] buff = new byte[5];
            //讀data
            int len = 0;

            while (fs.Length < filesize)
            {
                //取得長度
                len = stm.Read(buff, 0, buff.Length);
                fs.Write(buff, 0, len);

                //更新 progress bar
                if (progressBar1.Value + len <= progressBar1.Maximum)
                {
                    progressBar1.Value += len;
                    lbProgress.Text = "傳輸中... " + progressBar1.Value.ToString() + "/" + filesize.ToString();
                    progressBar1.Refresh();
                    Application.DoEvents();
                }
                //傳完
                if (fs.Length == filesize)
                {
                    progressBar1.Value = progressBar1.Maximum;
                    lbProgress.Text = "傳輸成功! " + filesize.ToString() + "/" + filesize.ToString();
                }
            }

            fs.Flush();
            //傳完,bfinish = true
             //清除資料流的緩衝區
            bfinish = (fs.Length == filesize);
            fs.Close();
            stm.Close();
        }
    }
    catch (System.Net.WebException we)
    {
        //若未傳完才要觸發 exception
        if (!bfinish)
            throw we;
    }
    ftpResp.Close();       
}

以上模仿參考至黑暗執行緒前輩的文章
相當讚的部落格!使我獲益良多
文章一  文章二
如有侵權我會立刻刪除!