使用 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 客户端发布请求

Ktor 1.0 发布:Kotlin Web 框架;GoLand 2018.3 正式版发布!| 更新

Kotlin Ktor API

Ktor + React 项目配置

如何确保清除 ktor websocket 客户端创建的所有 Kotlin 协程?