[c#] 斷點續傳下載文件[帶進度條類似迅雷]


       在.net里關於用Http下載文件,有HttpWebRequest實在是簡單。通常用這個組建可以輕松為自己量身定做一個類似於迅雷的下載軟件,只要你舍得花這個時間。當然,你還可以從socket方面入手,因為那個比用HTTP實現更底層,操作起來更細膩。但我們現在要說的與那無關,迅雷電驢雲雲,這些下載軟件實在是太方便了,以至於我們看起來毫無寫這方面軟件的必要了。但是,這方面的資料還是必須掌握一點,在很多方面都會用得着。

       當然還沒說到正題,先說下實現步驟:1.監視剪切板,判斷是否含有可以供下載的鏈接。2.建立下載任務,實時記錄下載進度。 3.進度條顯示進度。

先說下迅雷的下載格式:

thunder://QUFodHRwOi8veGlhemFpLnpvbC5jb20uY24vZG93bi5waHA/c29mdGlkPTExNDkyOSZzdWJjYXRpZD0zNDUmc2l0ZT0xMFpa

thunder://后面一連串的字符串是base64加密而成,因此,我們在下載迅雷協議格式的文件時,必須先解碼成Unicode文本。

AAhttp://xiazai.zol.com.cn/down.php?softid=114929&subcatid=345&site=10ZZ

去掉 “AA” “ZZ”就是地址了。


using System.IO;//引入輸入輸出功能
using System.Net;//網絡請求
using System.Text.RegularExpressions;//用於正則表達式字符串處理
using System.Runtime.InteropServices;//引入WinAPI功能函數
using System.Threading;//處理線程

准備一下功能函數
1.加載已經存在的INI配置文件

View Code
/// <summary>
        /// 為INI文件中指定的節點取得字符串
        /// </summary>
        /// <param name="lpAppName">欲在其中查找關鍵字的節點名稱</param>
        /// <param name="lpKeyName">欲獲取的項名</param>
        /// <param name="lpDefault">指定的項沒有找到時返回的默認值</param>
        /// <param name="lpReturnedString">指定一個字串緩沖區,長度至少為nSize</param>
        /// <param name="nSize">指定裝載到lpReturnedString緩沖區的最大字符數量</param>
        /// <param name="lpFileName">INI文件名</param>
        /// <returns>復制到lpReturnedString緩沖區的字節數量,其中不包括那些NULL中止字符</returns>
        [DllImport("kernel32")]
        public static extern int GetPrivateProfileString(
            string lpAppName,
            string lpKeyName,
            string lpDefault,
            StringBuilder lpReturnedString,
            int nSize,
            string lpFileName);
        #endregion
View Code
/// <summary>
        /// 從INI文件中讀取指定節點的內容
        /// </summary>
        /// <param name="section">INI節點</param>
        /// <param name="key">節點下的項</param>
        /// <param name="def">沒有找到內容時返回的默認值</param>
        /// <param name="def">要讀取的INI文件</param>
        /// <returns>讀取的節點內容</returns>
        public static string ReadString(string section, string key, string def, string fileName)
        {
            StringBuilder temp = new StringBuilder(1024);
            GetPrivateProfileString(section, key, def, temp, 1024, fileName);
            return temp.ToString();
        }

2.寫入INI文件

View Code
  /// <summary>
        /// 修改INI文件中內容
        /// </summary>
        /// <param name="lpApplicationName">欲在其中寫入的節點名稱</param>
        /// <param name="lpKeyName">欲設置的項名</param>
        /// <param name="lpString">要寫入的新字符串</param>
        /// <param name="lpFileName">INI文件名</param>
        /// <returns>非零表示成功,零表示失敗</returns>
        [DllImport("kernel32")]
        public static extern int WritePrivateProfileString(
            string lpApplicationName,
            string lpKeyName,
            string lpString,
            string lpFileName);
        #endregion

好了,准備工作做完了。先建立幾個全局變量。

       static string FileName = "";//記錄要下載的文件名
       static long FileLength = 0; //記錄文件大小
       static  int CompletedLength = 0;//記錄已完成的大小

下面完成下載功能,注釋里面都有。最適合初學的人看了。^!^

View Code
/// <summary>
        /// 以斷點續傳方式下載文件
        /// </summary>
        /// <param name="strFileName">下載文件的保存路徑</param>
        /// <param name="strUrl">文件下載地址</param>
        public void DownloadFile(string strFileName, string strUrl)
        {
            //打開上次下載的文件或新建文件
           int CompletedLength = 0;//記錄已完成的大小
          
            FileStream FStream;
            if (File.Exists(strFileName))
            {
                FStream = File.OpenWrite(strFileName);
                sPosstion = FStream.Length;
                FStream.Seek(sPosstion, SeekOrigin.Current);//移動文件流中的當前指針
            }
            else
            {
                FStream = new FileStream(strFileName, FileMode.Create);
                sPosstion = 0;
            }
            //打開網絡連接
            try
            {
                HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                if (CompletedLength > 0)
                    myRequest.AddRange((int)CompletedLength);//設置Range值
                //向服務器請求,獲得服務器的回應數據流
                HttpWebResponse webResponse = (HttpWebResponse)myRequest.GetResponse();
                FileLength = webResponse.ContentLength;//文件大小
                Stream myStream = webResponse.GetResponseStream();
                byte[] btContent = new byte[1024];
               if(count<=0) count += sPosstion;

                while ((CompletedLength = myStream.Read(btContent, 0, 1024)) > 0)
                {
                    FStream.Write(btContent, 0, CompletedLength);
                    count += CompletedLength;
                }
                FStream.Close();
                myStream.Close();
                MessageBox.Show("文件下載完成!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch
            {
                FStream.Close();
            }
        }

這就是最終的效果了。當然迅雷可不是這么簡單,要達到迅雷那樣的效果火候肯定是不夠的。這里面有很多新手值得去學習的地方,這個代碼不是我的原創,是我從網上下載后修改完成的。因為我覺得里面確實有很多可以學習鑒戒的地方,因此一時手癢供上給大家了。具體的源碼在評論處會補上,歡迎大家下載~!

教程每天都更新,歡迎大家繼續關注!


免責聲明!

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



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