OkHttp 中實現斷點續傳 demo

在 OkHttp 中實現斷點續傳主要通過以下步驟完成,核心是利用 HTTP 協議的?Range?請求頭指定下載范圍:

實現原理

  1. Range 請求頭:向服務器請求文件的特定字節范圍(如?Range: bytes=1024-

  2. 本地文件記錄:保存已下載的字節位置

  3. 206 狀態碼處理:服務器返回部分內容(HTTP 206 Partial Content)

  4. 文件追加寫入:從上次中斷的位置繼續寫入文件

完整實現代碼(Kotlin/Java)

kotlin

import okhttp3.*
import java.io.File
import java.io.IOException
import java.io.RandomAccessFileclass ResumeDownloader(private val client: OkHttpClient = OkHttpClient()
) {fun download(url: String, file: File, listener: ProgressListener? = null) {// 1. 獲取已下載字節數val downloadedBytes = if (file.exists()) file.length() else 0L// 2. 創建帶Range頭的請求val request = Request.Builder().url(url).header("Range", "bytes=$downloadedBytes-").build()client.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {listener?.onError(e)}override fun onResponse(call: Call, response: Response) {if (!response.isSuccessful) {listener?.onError(IOException("Unexpected code: ${response.code}"))return}// 3. 檢查服務器是否支持斷點續傳val isResumeSupported = response.code == 206 // Partial Contentval totalBytes = response.header("Content-Length")?.toLongOrNull() ?: -1Lval finalTotalBytes = if (isResumeSupported) {downloadedBytes + (totalBytes)} else {totalBytes}// 4. 處理響應體response.body?.use { body ->RandomAccessFile(file, "rw").use { output ->// 移動到文件末尾追加output.seek(downloadedBytes)val input = body.byteStream()val buffer = ByteArray(8192)var bytesRead: Intvar progress = downloadedBytes// 5. 寫入文件while (input.read(buffer).also { bytesRead = it } != -1) {output.write(buffer, 0, bytesRead)progress += bytesRead// 更新進度listener?.onProgress(progress, finalTotalBytes)}listener?.onComplete(file)}}}})}interface ProgressListener {fun onProgress(currentBytes: Long, totalBytes: Long)fun onComplete(file: File)fun onError(e: Exception)}
}

Java 版本核心代碼

java

// 創建帶Range頭的請求
long downloadedBytes = file.length();
Request request = new Request.Builder().url(url).addHeader("Range", "bytes=" + downloadedBytes + "-").build();// 處理響應
try (Response response = client.newCall(request).execute()) {if (response.code() == 206) { // Partial Contenttry (RandomAccessFile output = new RandomAccessFile(file, "rw");InputStream input = response.body().byteStream()) {output.seek(downloadedBytes);byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = input.read(buffer)) != -1) {output.write(buffer, 0, bytesRead);}}}
}

關鍵注意事項

  1. 服務器支持檢查

    • 成功時返回?HTTP 206(部分內容)

    • 失敗時返回 200(完整文件)或 416(范圍請求錯誤)

    • 響應頭需包含?Accept-Ranges: bytes

  2. 文件處理

    • 使用?RandomAccessFile?實現文件隨機訪問

    • 通過?seek()?定位到文件末尾

    • 避免覆蓋已下載內容

  3. 進度跟蹤

    • 總大小 = 已下載大小 +?Content-Length

    • 實時計算:currentBytes += bytesRead

  4. 異常處理

    • 網絡中斷時保存當前進度

    • 重新下載時使用最新文件長度

增強功能建議

  1. 進度持久化:使用數據庫記錄下載狀態

  2. 暫停/恢復:暴露下載控制接口

  3. 多線程下載:分割文件范圍并行下載(需服務器支持)

  4. 完整性校驗:下載完成后驗證文件 MD5/SHA1

示例用法:

kotlin

val downloader = ResumeDownloader()
val file = File(context.filesDir, "largefile.zip")downloader.download("https://example.com/largefile.zip", file,object : ResumeDownloader.ProgressListener {override fun onProgress(current: Long, total: Long) {val percent = (current * 100 / total).toInt()updateProgressBar(percent)}override fun onComplete(file: File) {showToast("下載完成")}override fun onError(e: Exception) {showError(e.message)}}
)

通過此實現,OkHttp 可在網絡中斷后自動從斷點恢復下載,大幅提升大文件下載體驗。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84318.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84318.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84318.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

函數中的Callable

在編程中,?Callable(可調用對象)?? 是指任何可以通過 () 操作符調用的對象。在函數和類設計的上下文中,Callable 通常指代可以被調用的實體,例如函數、方法、Lambda表達式或實現了 __call__ 方法的對象。以下是詳細…

MySQL學習之觸發器

文章目錄 前言什么是觸發器(Trigger)?觸發器的特點 MySQL中觸發器的用法創建NEW 與 OLD舉例其他操作 注意事項后續內容參考目錄 前言 閱讀本文前請注意最后編輯時間,文章內容可能與目前最新的技術發展情況相去甚遠。歡迎各位評論…

AIGC 基礎篇 Python基礎 04 for循環與while循環

今天,我們來講Python里面的循環部分 1.for循環 for i in range(1,10,2):print(i) 這是一個簡單但是完整的for循環,里面包含了for循環的所有結構 首先注意格式是“for 變量 in range(取得到的起始值,取不到的終點值,步長)” …

安寶特方案丨XRSOP人員作業標準化管理平臺:AR智慧點檢驗收套件

在選煤廠、化工廠、鋼鐵廠等過程生產型企業,其生產設備的運行效率和非計劃停機對工業制造效益有較大影響。 隨著企業自動化和智能化建設的推進,需提前預防假檢、錯檢、漏檢,推動智慧生產運維系統數據的流動和現場賦能應用。同時,…

每日算法 -【Swift 算法】三數之和最接近目標值

?? Swift 實現:三數之和最接近目標值(3Sum Closest) ? 前言 在算法學習過程中,經典的“三數之和”系列題目是很多人通往進階路上的一道坎。今天我們來介紹其中一個非常實用的變種問題 —— 三數之和最接近目標值(3Sum Closest),并使用 Swift 實現一個高效的解法。 …

python打卡day50@浙大疏錦行

知識點回顧: resnet結構解析CBAM放置位置的思考針對預訓練模型的訓練策略 差異化學習率三階段微調 ps:今日的代碼訓練時長較長,3080ti大概需要40min的訓練時長 作業: 好好理解下resnet18的模型結構嘗試對vgg16cbam進行微調策略 R…

虛幻引擎5-Unreal Engine筆記之SET節點的輸出引腳獲取設置后的最新變量值

虛幻引擎5-Unreal Engine筆記之SET節點的輸出引腳獲取設置后的最新變量值 code review! 一個變量的“SET”節點 retrieve 是動詞,意思是“檢索、獲取、取回”。 retrieves 只是當主語是第三人稱單數(比如 he、she、it 或單個人/物)時使用的…

編譯原理實驗 之 TINY 解釋測試目標代碼

文章目錄 實驗任務1任務2 本次的實驗是在前三次TINYC的基礎上的一個測試,所以完成前三次的實驗是基礎 編譯原理 之 實驗一 編譯原理實驗 之 Tiny C語言編譯程序實驗 語法分析 編譯原理實驗 之 TINY 之 語義分析(第二次作業 首先將新的文件復制到先前的…

CanFestival移植到STM32G4

文章目錄 一、準備工作二、軟件配置三、移植CanFestival參考 一、準備工作 1、獲取Canfestival源碼 2、Python下載 3、wxPython下載 4、CanFestival字典生成 5、安裝參考 Python2.7.15及wxPython2.8百度云盤下載地址:https://pan.baidu.com/s/1bRS403m4B31m4ovSJ-_…

iOS性能調優實戰:借助克魔(KeyMob)與常用工具深度洞察App瓶頸

在日常iOS開發過程中,性能問題往往是最令人頭疼的一類Bug。尤其是在App上線前的壓測階段或是處理用戶反饋的高發期,開發者往往需要面對卡頓、崩潰、能耗異常、日志混亂等一系列問題。這些問題表面上看似偶發,但背后往往隱藏著系統資源調度不當…

第十三章 RTC 實時時鐘

第十三章 RTC 實時時鐘 目錄 第十三章 RTC 實時時鐘 1 RTC簡介 1.1 主要特性 2 功能描述 2.1 概述 2.2 復位過程 2.3 讀RTC寄存器 2.4 配置RTC寄存器 2.5 RTC標志的設置 3 RTC寄存器描述 3.1 RTC控制寄存器高位(RTC_CRH) 3.2 RTC控制寄存器低位(RTC_CRL) 3.3 RTC預…

618來了,推薦京東云服務器

2核2G3M,49元/1年,348元/3年 2核4G5M,149元/1年,518元/3年 4核8G5M,368元/1年,1468元/3年 8核16G5M,1258元/1年,3498元/3年 8核32G10M,1498元/1年,4268元/3年 活動地址:https://3.cn/2hT-F6AX

數據庫邏輯刪除,唯一性約束究極解決方案

文章目錄 一、寫在前面二、解決方案1、業務邏輯層面控制2、物理刪除數據歸檔3、is_delete !0的都認為是刪除(推薦)4、MySQL 函數索引(表達式索引)(需 MySQL 8.0)(推薦)5、部分索引&a…

3-存儲系統

一-基本概念 二-主存儲器 三-主存儲器與CPU的連接 四-外部存儲器 五-高速緩沖存儲器 六-虛擬存儲器

華為0528筆試

第三題 題目 給定一個二維數組 mountainMap 表示一座山的地圖,數組中的每個元素 mountainMap[x][y] 代表坐標 (x, y) 處山的高度。登山員從山底出發,爬到山峰。 山底的含義:mountainMap中高度為0的坐標點。 山峰的含義:mountain…

Redis的過期策略和淘汰策略

Redis的過期策略和淘汰策略 想象一下周末的大型超市:生鮮區的酸奶貼著"今日特價"標簽,促銷員定時檢查這些商品的保質期;而倉庫管理員正根據"先進先出"原則整理貨架,確保商品不會過期積壓。這種高效的商品管理…

laravel8+vue3.0+element-plus搭建方法

創建 laravel8 項目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安裝 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …

【HarmonyOS 5】 影視與直播詳以及 開發案例

&#x1f3a5; ?一、超高清低延遲直播? ?4K/8K硬解能力?&#xff1a;通過鴻蒙媒體引擎實現15Mbps碼率視頻流穩定解碼&#xff0c;華為Pura X實測端到端延遲<80ms?分布式渲染?&#xff1a;支持手機拍攝→智慧屏導播→平板監看的工作流協同&#xff0c;設備間傳輸延遲&…

Tunna工具實戰:基于HTTP隧道的RDP端口轉發技術

工具概述 Tunna是一款利用HTTP/HTTPS隧道進行TCP通信的滲透測試工具&#xff0c;由SECFORCE團隊開發并開源。該工具主要應用于需要繞過防火墻限制的場景&#xff0c;通過Webshell實現內網服務的端口轉發&#xff0c;特別適合在僅開放80/443端口的環境中建立TCP連接。 項目地址…

c# Autorest解析

AutoRest 工具生成用于訪問 RESTful Web 服務的客戶端庫。AutoRest 的輸入是使用 OpenAPI 規范格式描述 REST API 的規范。OpenAPI(f.k.a Swagger)規范代碼生成器。支持 C#、PowerShell、Go、Java、Node.js、TypeScript、Python。 安裝 AutoRest 在 Windows、MacOS 或 Linux …