使用 Ktor HTTP 客户端(和 kotlinx.io?)直接将可恢复下载到文件
Posted
技术标签:
【中文标题】使用 Ktor HTTP 客户端(和 kotlinx.io?)直接将可恢复下载到文件【英文标题】:Using Ktor HTTP Client (and kotlinx.io?) for resumable downloads directly to a file 【发布时间】:2021-03-07 10:07:59 【问题描述】:我以前没有处理过(大)HTTP 下载,所以我对这个话题真的不太了解。
所以,我想做的是以编程方式将文件从互联网直接下载到本地文件系统中。如果下载是可恢复的,那也很好。对于 Java,我发现 this Baeldung article 基本上解释了如何做到这一点。
但是,我不使用 Java,而是使用 Kotlin。更具体地说,我使用 Ktor HTTP 客户端(使用 Apache 引擎,但如果需要我可以切换它)。我想知道是否有办法以与上述文章中相同的方式使用此客户端。基本上,我会调用 GET 请求,但我会告诉客户端将字节流式传输到指定的File
位置。当下载中断时,我会查询当前状态的文件大小,并在这个字节位置(PartialContent)恢复它。
我发现了
-
Ktor 服务器支持这个:https://ktor.io/docs/partial-content.html
kotlinx-io
库可能会有所帮助(因为与文章的类比):https://github.com/Kotlin/kotlinx-io
但是,我不知道如何将所有内容放在一起并“连接松散的电线”以使其全部正常工作。似乎我的问题对于简单的谷歌搜索来说太具体了,这就是我现在求助于 SO 的原因。如果任何对 Ktor 和 HTTP 下载有一定经验的人可以为我提供一些启示,我们将不胜感激!
PS 在进一步的进展中,this SO question 的答案可能也很有趣。
版本数据:
Kotlin/JVM 1.4.20 Ktor 1.4.1 OpenJDK 11【问题讨论】:
【参考方案1】:基本思想是通过发出HEAD
请求来获取总内容长度,然后在Range 标头的帮助下迭代下载内容。这是一个示例实现:
suspend fun main()
val client = HttpClient()
client.download(
"https://weq714976.live-website.com/wp-content/uploads/2019/03/WeQ-Influencers-Logo-1568x812.png",
File("result.png")
)
suspend fun HttpClient.download(url: String, outFile: File, chunkSize: Int = 1024)
val length = head<HttpResponse>(url).headers[HttpHeaders.ContentLength]?.toLong() as Long
val lastByte = length - 1
var start = outFile.length()
val output = FileOutputStream(outFile, true)
while (true)
val end = min(start + chunkSize - 1, lastByte)
get<HttpResponse>(url)
header("Range", "bytes=$start-$end")
.content.copyTo(output)
if (end >= lastByte) break
start += chunkSize
【讨论】:
感谢您的回答!我将其标记为已接受的答案,因为它通常是完成此任务的正确方法。然而这并不是我最终解决它的方式,因为我发现我正在查询的 API 不支持 Range 标头......无论如何,感谢您的帮助!以上是关于使用 Ktor HTTP 客户端(和 kotlinx.io?)直接将可恢复下载到文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ktor kotlin 通过 POST 发送 JSON 字符串?
无法在 kotlin js 中使用 ktor 客户端发布请求