You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Ktor实现并行流式下载?当前先存内存再写入文件

解决Ktor下载文件先存内存再写入的问题并实现并行下载

一、先实现流式下载(边下载边写入文件)

你当前的代码会先把整个文件加载到内存再写入,是因为httpClient.request()默认会等待完整响应返回。改用HttpStatement可以实现流式处理,边接收数据边写入文件,避免内存占用过高,同时解决前期无响应的问题:

val httpClient = HttpClient(OkHttp) // 或Android引擎
val targetFile = File(cacheDir, "test.foo")

httpClient.prepareRequest {
    url("http://example.com/large_file.dat")
}.execute { response ->
    response.bodyAsChannel().copyAndClose(targetFile.writeChannel())
}

prepareRequest返回HttpStatement,execute会在响应开始接收时就回调,而非等整个响应完成,这样就能实时把数据写入文件。

二、实现并行分块下载

并行下载需要借助HTTP的Range请求头,将文件拆分为多个块同时下载,最后合并成完整文件,步骤如下:

1. 获取文件总大小

先发送HEAD请求获取文件的总大小,确认服务器支持分块下载(响应头需包含Accept-Ranges: bytes):

val fileUrl = "http://example.com/large_file.dat"
val fileSize = httpClient.head(fileUrl) {
    onSuccess { response ->
        response.headers["Content-Length"]?.toLong() ?: 0L
    }
}

2. 分块并启动多协程并行下载

定义单块大小(比如1MB),计算块的区间,为每个块启动独立协程下载:

val chunkSize = 1024 * 1024 // 1MB每块
val chunks = (0..fileSize step chunkSize).map { start ->
    val end = minOf(start + chunkSize - 1, fileSize - 1)
    start to end
}

// 创建临时文件存储每个块
val tempChunkFiles = chunks.mapIndexed { index, _ ->
    File(cacheDir, "temp_chunk_$index")
}

// 并行下载所有块
coroutineScope {
    chunks.forEachIndexed { index, (start, end) ->
        launch {
            httpClient.prepareRequest {
                url(fileUrl)
                header("Range", "bytes=$start-$end")
            }.execute { response ->
                response.bodyAsChannel().copyAndClose(tempChunkFiles[index].writeChannel())
            }
        }
    }
}

3. 合并块文件为完整文件

所有块下载完成后,按顺序合并到目标文件,最后清理临时文件:

val targetFile = File(cacheDir, "test.foo")
targetFile.outputStream().use { output ->
    tempChunkFiles.forEach { chunkFile ->
        chunkFile.inputStream().use { input ->
            input.copyTo(output)
        }
        chunkFile.delete()
    }
}

额外注意事项

  • 若服务器不支持Range请求,分块下载会失效,需降级为普通流式下载。
  • 需处理下载失败的场景:比如单个块下载失败时,要重新发起该块的下载请求。
  • 可根据设备性能调整块大小和并发协程数量,避免资源过度占用。

内容的提问来源于stack exchange,提问作者AndreKR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:01:09