我們寄希望於萬能的解決方案,但是現實的情況總是很糟糕。在軟件編程的世界中,技術分散的情況尤為嚴重,且不說各種語言擁有的優勢不能融合,單就一 門語言而言,就擁有眾多的技術和相關技術需要學習。網絡編程就是這種情況,tcp、udp、http和soap相關的協議(ftp不會玩),我們不得不在 同一個應用中使用不同難以整合的技術。tcp講究精准,udp講究性能,http對於穿越外網有這天然的優勢,soap對於講究編程模型的人來說是福音。
其實斷點續傳,眾多技術都可以實現,只是想難易程度而以。經過比較分析發現,http對於斷點下載比較容易實現,它最成功的地方在於,不需要服務端的實現,只需將需要下載的文件放置在iis服務器中即可。
下面我會根據下面一段代碼分析http協議的
/// <summary>
/// 下載方法
/// </summary>
/// <param name="uri">下載地址的URI</param>
public void DownLoad(object obj)
{
//比如uri=http://localhost/Rabom/1.rar;iis就需要自己配置了。
string uri = obj.ToString();
//截取文件名
string fileName = uri.Substring(uri.LastIndexOf(@"/") + 1);
//構造文件完全限定名,准備將網絡流下載為本地文件
string fileFullName = Application.StartupPath + @"\download\" + fileName;
//構造文件的配置文件的完全完全限定名
string fileCfgName = Application.StartupPath + @"\download\" + fileName+".cfg";
//本地構造文件流
FileStream fs;
//本地配置文件流
FileStream fsCfg;
if (File.Exists(fileFullName))
{
//如果存在配置文件,則繼續下載
if (File.Exists(fileCfgName))
{
fs = new FileStream(fileFullName, FileMode.Append, FileAccess.Write, FileShare.Write);
fsCfg = fs = new FileStream(fileFullName, FileMode.Append, FileAccess.Write, FileShare.Write);
}
else
{
return;//暫且這樣
}
}
else
{
fs = new FileStream(fileFullName, FileMode.Create);
fsCfg = new FileStream(fileCfgName, FileMode.Create);
}
//開辟內存空間
byte[] buffer = new byte[512];
//請求地址
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
//請求開始位置
request.AddRange((int)fs.Length);
//獲取網絡流
Stream ns = request.GetResponse().GetResponseStream();
//獲取文件實際長度
long contentLength = request.GetResponse().ContentLength;
//獲取文件讀取到的長度
int length = ns.Read(buffer, 0, buffer.Length);
while (length > 0)
{
//將字節數組寫入流
fs.Write(buffer, 0, buffer.Length);
//繼續下載
buffer = new byte[512];
length = ns.Read(buffer, 0, buffer.Length);
}
ns.Close();
fs.Close();
fsCfg.Close();
}
在上面的代碼中,比較重要的就是類HttpWebRequest,這個類封裝了http協議訪問網絡資源的方法,與WebClient不同的是,HttpWebRequest允許我們使用網絡流的方式進行下載,我們通過URI創建一個網絡
流,我們就可以開始獲取我們需要的數據了。在http協議的報文中,會進行詳細的描述,當然描述的內容
很多,HttpWebRequest都幫我們做了,說點題外話,http協議會將我們計算機環境寫進報文,其中包括計算機
名,計算機所在的ip地址。當然也包括我們所講的斷點下載的關鍵報文Range,這個報文就是我們需要開始下載文件的起始位置,這樣我們就可以根據本地文件已經下載了多少,為斷點下載時所要求的起始位置提供依據。
本地文件剛創建的時候,fs.Lenght為0所以我們在iis服務器上請求的網絡流的游標是在流的起始位置,
當我們停止下載后,再度下載該資源的時候,網絡流的游標位置會根據range的值設置到相應的位置,這樣我們就可以斷點下載了。
如果你是網絡編程的新手,那么本文的內容不適合你,因為文中涉及大量的網絡編程的概念,你需要去一一掌握然后才能理解本文;如果你是有網絡編程的經驗,而且不知道這種斷點下載的方式,那么我相信你一定學到了!
文章來源:http://blog.sina.com.cn/s/blog_62b0d0ef0100mnmj.html