java 断点续传 开源_java断点续传原理
先說說斷點續(xù)傳的原理:這是HTTP 1.1協(xié)議的一部分,并不需要客戶端特意去做多么復(fù)雜的事情。以前我曾經(jīng)看過一個單位的技術(shù)標(biāo)書,其中有下載的斷點續(xù)傳這一要求,給出的offer居然還挺高的...
簡單的說,只要利用了HTTP協(xié)議(http://www.ietf.org/rfc/rfc2616.txt)中的如下字段來和服務(wù)器端交互,就可以實現(xiàn)文件下載的斷點續(xù)傳:
Range : 用于客戶端到服務(wù)器端的請求,可通過該字段指定下載文件的某一段大小,及其單位。典型的格式如:
Range: bytes=0-499 下載第0-499字節(jié)范圍的內(nèi)容
Range: bytes=500-999? 下載第500-999字節(jié)范圍的內(nèi)容
Range: bytes=-500? 下載最后500字節(jié)的內(nèi)容
Range: bytes=500-? 下載從第500字節(jié)開始到文件結(jié)束部分的內(nèi)容(這是最常用的一種格式)
Range: bytes=0-0,-1? 下載第一以及最后一個字節(jié)的內(nèi)容(這個看上去有點變態(tài)...)
Accept-Ranges : 用于服務(wù)器端到客戶端的應(yīng)答,客戶端通過該字段可以判斷服務(wù)器是否支持?jǐn)帱c續(xù)傳(注意RFC中注明了這一部分并不是必須的)。格式如下:
Accept-Ranges: bytes? 表示支持以bytes為單位進行傳輸。
Accept-Ranges: none? 表示不支持
Content-Ranges : 用于服務(wù)器端到客戶端的應(yīng)答,與Accept-Ranges在同一個報文內(nèi),通過該字段指定了返回的文件資源的字節(jié)范圍。格式如下:
Content-Ranges: bytes 0-499/1234? 大小為1234的文件的第0-499字節(jié)范圍的內(nèi)容
Content-Ranges: bytes 734-1233/1234? 大小為1234字節(jié)的文件的第734-結(jié)尾范圍的內(nèi)容
據(jù)此我們可以知道,斷點續(xù)傳這個功能是需要客戶端和服務(wù)器端同時支持才能完成。
Android平臺面向開發(fā)者提供了DownloadManager這個服務(wù)(service),可以用來完成下載,同時異步地得到下載進度的實時更新提示。原生的瀏覽器,Android Market以及GMail等客戶端都使用了該接口。該接口也部分的提供了斷點續(xù)傳功能:如果在下載過程中遇到網(wǎng)絡(luò)錯誤,如信號中斷等,DownloadManager會在網(wǎng)絡(luò)恢復(fù)時嘗試斷點續(xù)傳繼續(xù)下載該文件。但不支持由用戶發(fā)起的暫停然后斷點續(xù)傳。
要擴展該功能也不難,只要為下載任務(wù)新增一種狀態(tài)(類似paused_by_user),以及相關(guān)邏輯即可,這里暫不贅述,把話題引到一些常見問題上。
1. 關(guān)于ETag
RFC中的定義有些抽象,簡單的說,ETag可以用來標(biāo)識/保證文件的唯一性或完整性,你可以把它看作是服務(wù)器為某個文件生產(chǎn)的唯一標(biāo)識值,每次文件有更新該值就會變化。通過這種機制客戶端可以檢查某個文件在斷點續(xù)傳(當(dāng)然它不僅僅用于斷點續(xù)傳)的前后是否有所改動:如果ETag改變了就應(yīng)該重新下載整個文件以保證它的完整性。
但是在現(xiàn)實環(huán)境中,有一些服務(wù)器并不返回ETag字段,同時它又是支持?jǐn)帱c續(xù)傳的,這種情況下原生的Android就會認(rèn)為服務(wù)器端不支持?jǐn)帱c續(xù)傳。這應(yīng)該不是什么bug,僅僅是這么實現(xiàn)而已。還有更麻煩的情況是,有些服務(wù)器給了錯誤的ETag,但文件是從未更改的,這時候要想從客戶端修改這個“bug”,估計只能忽略ETag值了。
2. 關(guān)于HTTP 206
RFC中定義了斷點續(xù)傳時服務(wù)器端的應(yīng)答情況:如果支持且返回的內(nèi)容如請求所要求的那樣,是該文件的一部分,則使用HTTP 206狀態(tài)碼;如果不支持,或需要返回整個文件,則使用HTTP 200狀態(tài)碼。但是現(xiàn)實網(wǎng)絡(luò)中有些服務(wù)器不管三七二十一,都返回200。沒辦法,如果還是想從客戶端來修改這個“bug”,那就多做一些判斷處理吧:如果服務(wù)器指定了“Content-Ranges”,就忽略HTTP 200的狀態(tài)碼。
附圖一張,簡述流程。見附件
補記:有一次被問起如何在原生的Android手機上暫停一個下載任務(wù),回頭再斷點續(xù)傳。我想是不是可以在下載過程中將手機信號關(guān)閉,下次再打開手機信號時,那個下載任務(wù)就可以自動接著續(xù)傳了(當(dāng)然前提是服務(wù)器支持)...這個用例沒多大實用價值,懶得實測了
總結(jié)
以上是生活随笔為你收集整理的java 断点续传 开源_java断点续传原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: laravel项目中css样式表的背景图
- 下一篇: POJ2190 HDU2714 ISBN