import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
import io.ktor.client.features.*
import io.ktor.client.features.cookies.*
import io.ktor.client.features.get
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import io.ktor.utils.io.streams.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream
suspend fun main() {
val url = "https://gw.alicdn.com/imgextra/i2/O1CN013MNdBO1ubErlsGeSo_!!0-fleamarket.jpg"
HttpClient(CIO){
install(HttpCookies)
}.use { httpClient ->
// httpClient.download(url, File("./5.jpg").outputStream())
val httpStatement: HttpStatement = httpClient.get(url)
val fileOutputStream=File("./6.jpg").outputStream()
download(httpStatement, fileOutputStream)
}
}
suspend fun HttpClient.download(url: String, fileOutputStream: FileOutputStream) = withContext(Dispatchers.IO) {
this@download.get<HttpStatement>(url).execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.receive()
while (!channel.isClosedForRead) {
val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
if (!packet.isEmpty) {
fileOutputStream.writePacket(packet)
}
}
}
}
// 利用ktor client下载文件。能够实现高度自定义的HttpStatement
suspend fun download(httpStatement: HttpStatement, fileOutputStream: FileOutputStream) = withContext(Dispatchers.IO) {
httpStatement.execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.receive()
while (!channel.isClosedForRead) {
val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
if (!packet.isEmpty) {
fileOutputStream.writePacket(packet)
}
}
}
}
ktor下载文件流