斷點(diǎn)續(xù)傳

1.斷點(diǎn)續(xù)傳

定義:我們有時(shí)在邊聊天邊下載大文件時(shí),感覺(jué)很卡,這時(shí)可以暫停下載任務(wù),聊完天再繼續(xù)下載文件。這就是斷點(diǎn)下載

實(shí)現(xiàn)方式:iOS中利用NSURLSession可以進(jìn)行文件斷點(diǎn)下載,下面就一起來(lái)實(shí)現(xiàn)它吧。

知識(shí)儲(chǔ)備:1.對(duì)NSURLSesiion的認(rèn)識(shí)

NSURLSesiion是蘋(píng)果在iOS7推出的一個(gè)類,它具備了NSURLConnection所具備的方法,同時(shí)也比它更強(qiáng)大。蘋(píng)果推出它的目的大有取代NSURLConnection的趨勢(shì)或者目的。

2.NSURLSesiion的作用

實(shí)現(xiàn)對(duì)文件的下載與上傳。在NSURLSesiion中,任何請(qǐng)求都可以被看做是一個(gè)任務(wù)。而NSURLSesiionData有兩個(gè)子類:NSURLSessionDownlaodTask實(shí)現(xiàn)文件下載和NSURLSessionUploadTask實(shí)現(xiàn)文件上傳。

3.NSURLSession的獲取

NSURLSession的獲取可以用NSURLSessionDownloadTaskdelegate的方法獲取,但是必須得遵循這個(gè)協(xié)議。獲取如下:

NSURLSessionDonfiguration*configuration=[NSURLSessionDonfiguration defaultSessionconfiguration];

self.session=[NsURLSessionsessionWithConfiguration:NSURLSessionDonfiguration delegate: self?delegateQueue:[NSOperationQueue mainQueue]];

4.下載任務(wù)的創(chuàng)建

NSURLSessionDownlaodTask* task=[self.sessiondownloadTaskWithURL:url]

5.NSURLSessionDownloadDelegate的代理方法:

它有三個(gè)方法:

6.沙盒路徑的獲取

NSString*path=[NSSearchPathForDiretoriesInDomains(NSDocumentDirectoriy,NSUserDomainMask, YES ) ?lastObject];

7.caches路徑的獲取及里面文件名的創(chuàng)建

NSString *caches=[NSSearchPathForDiretoriesInDomains(NSCachesDirectoriy,NSUserDomainMask, YES ) ?lastObject];

NSString* filename=[cachesstringByAppendingPathComponent:downloadTask.response.suggestedname];

第二部分對(duì)程序幾個(gè)屬性的說(shuō)明

1.resumeData

該參數(shù)包含了繼續(xù)下載文件的位置信息。也就是說(shuō),當(dāng)你下載了10M得文件數(shù)據(jù),暫停了。那么你下次繼續(xù)下載的時(shí)候是從第10M這個(gè)位置開(kāi)始的,而不是從文件最開(kāi)始的位置開(kāi)始下載。因而為了保存這些信息,所以才定義了這個(gè)NSData類型的這個(gè)屬性:resumeData

2. ?task

該參數(shù)的類型是NSURLSessionDownloadTask。因?yàn)樵诔绦蛘{(diào)用暫停(pause)這個(gè)方法時(shí),必須擁有這個(gè)屬性,怎么拿到它了?最好的辦法就是讓控制器擁有這個(gè)屬性。

3. session

該參數(shù)的類型是NSURLSession.在程序調(diào)用繼續(xù)下載(resume)這個(gè)方法時(shí),必須擁有這個(gè)session。因?yàn)橹暗娜蝿?wù)task被取消了,無(wú)法在復(fù)用了,所以用懶加載的方法,讓session只創(chuàng)建一次,同時(shí)也讓控制器擁有了這個(gè)屬性。


*使用NSURLSessionDataTask可以很輕松實(shí)現(xiàn)斷點(diǎn)續(xù)傳,可是有個(gè)致命的缺點(diǎn)就是無(wú)法進(jìn)行后臺(tái)下載

二:對(duì)NSURLSessionDownloadTask解釋

? ? ? ? 使用NSURLSessionDataTask可以很輕松實(shí)現(xiàn)斷點(diǎn)續(xù)傳,可是有個(gè)致命的缺點(diǎn)就是無(wú)法進(jìn)行后臺(tái)下載,一點(diǎn)應(yīng)用程序進(jìn)入了后臺(tái),便會(huì)停止下載。所以無(wú)法滿足我們的需求。而NSURLSessionDownloadTask是唯一可以實(shí)現(xiàn)后臺(tái)下載的類,所以我們只能從這個(gè)類進(jìn)行下手了。

那么本篇我們就來(lái)談?wù)勱P(guān)于應(yīng)用程序隨時(shí)可能被殺死的情況下,如何進(jìn)行斷點(diǎn)續(xù)傳。

(一):關(guān)于斷點(diǎn)續(xù)傳原理:

首先,如果想要進(jìn)行斷點(diǎn)續(xù)傳,那么需要簡(jiǎn)單了解一下斷點(diǎn)續(xù)傳的工作機(jī)制,在HTTP請(qǐng)求頭中,有一個(gè)Range的關(guān)鍵字,通過(guò)這個(gè)關(guān)鍵字可以告訴服務(wù)器返回哪些數(shù)據(jù)給我。

比如:

bytes=500-999 表示第500-第999字節(jié)

bytes=500- 表示從第500字節(jié)往后的所有字節(jié)

然后我們?cè)俑鶕?jù)服務(wù)器返回的數(shù)據(jù),將得到的data數(shù)據(jù)拼接到文件后面,就可以實(shí)現(xiàn)斷點(diǎn)續(xù)傳了。

(二):關(guān)于文件下載與暫停的分析:

1.當(dāng)使用NSURLSessionDownloadTask進(jìn)行下載的時(shí)候,系統(tǒng)會(huì)在cache文件夾下創(chuàng)建一個(gè)下載的路徑.(路徑下會(huì)有一個(gè)以"CFNetworking"打頭的.tmp文件(以下簡(jiǎn)稱"下載文件"防止混淆),這個(gè)就是我們正在下載中的文件)

2.調(diào)用cancelByProducingResumeData:方法后,會(huì)得到一個(gè)data文件,通過(guò)String格式化后,發(fā)現(xiàn)是一個(gè)XML文件.

3.XML里面包含了關(guān)于.tmp文件的一些關(guān)鍵點(diǎn)的描述,包括"Range","key","下載文件的路徑"等等.而原本存在于download文件下的下載文件,則被移動(dòng)到了系統(tǒng)tmp文件夾目錄下.

4.當(dāng)我們?cè)俅芜M(jìn)行resume操作的時(shí)候,下載文件則又被移回到了download文件夾下。


(三):關(guān)于程序被殺掉的斷點(diǎn)續(xù)傳resumeData

根據(jù)上面的分析,基本可以得到以下結(jié)論:

1.DownloadTask每次進(jìn)行斷點(diǎn)續(xù)傳的時(shí)候,會(huì)根據(jù)data文件中的"路徑Key"去尋找下載文件,然后校驗(yàn)后再根據(jù)"Range"屬性去進(jìn)行斷點(diǎn)續(xù)傳。

2.download文件夾中存放的只會(huì)是下載中的文件,一旦暫停就會(huì)被移動(dòng)到tmp文件夾下。

3.每個(gè)暫停得到的data文件,與下載文件一一對(duì)應(yīng)。

3.斷點(diǎn)續(xù)傳只與tmp文件夾中的文件有關(guān)。

具體實(shí)現(xiàn)

為了節(jié)省性能,我嘗試查找關(guān)于程序被殺掉前的回調(diào),但是很遺憾失敗了,因?yàn)槲覠o(wú)法控制到知道是哪一秒去保存進(jìn)度,所以我只能每隔一段時(shí)間保存一次。設(shè)置一個(gè)Bool變量用來(lái)判斷是否正在下載中,同時(shí)用一個(gè)周期事件每隔一段時(shí)間暫停一次(聽(tīng)上去挺笨的,但是這似乎是唯一獲得data文件的辦法了)。然后保存data文件和拷貝tmp文件夾下的下載文件到安全目錄下(因?yàn)閠mp文件夾據(jù)說(shuō)隨時(shí)可能清空)。

當(dāng)再次下載的時(shí)候,先是從安全目錄下取到下載文件,刪除tmp文件夾中原有的同名文件,然后copy到tmp目錄下,最后利用保存的data文件進(jìn)行再次downloadTaskWithResumeData操作,就可以實(shí)現(xiàn)再次下載了。

利與弊

好處:

1.DownloadTask可以后臺(tái)下載,不必保持app在前臺(tái),用戶體驗(yàn)很好。

2.實(shí)現(xiàn)了任意時(shí)間點(diǎn)殺掉進(jìn)程后,仍然可以斷點(diǎn)續(xù)傳。

缺陷:

1.因?yàn)樘O(píng)果沒(méi)有提供很好的API,所以會(huì)有一個(gè)循環(huán)檢查,每隔一段時(shí)間會(huì)暫停個(gè)一秒左右,效率略有降低。

2.如果設(shè)置保存間隔過(guò)長(zhǎng),中間殺掉進(jìn)程可能會(huì)損失較多進(jìn)度。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容