Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 在Ktor中,如何将InputStream流式传输到HttpClient请求';谁的身体?_Kotlin_Ktor_Ktor Client - Fatal编程技术网

Kotlin 在Ktor中,如何将InputStream流式传输到HttpClient请求';谁的身体?

Kotlin 在Ktor中,如何将InputStream流式传输到HttpClient请求';谁的身体?,kotlin,ktor,ktor-client,Kotlin,Ktor,Ktor Client,我正在使用并且我有一个InputStream对象,我想用它作为我在下一行发出的HttpClient请求的主体。直到Ktor 0.95之前,有一个对象似乎就是这样做的,但它在1.0.0版本时已从Ktor中删除(不幸的是,无法找出原因) 我可以使用ByteArrayContent(见下面的代码)使其工作,但我宁愿找到一个不需要将整个InputStream加载到内存中的解决方案 ByteArrayContent(input.readAllBytes()) 这段代码是一个简单的测试用例,模拟了我试图实

我正在使用并且我有一个InputStream对象,我想用它作为我在下一行发出的HttpClient请求的主体。直到Ktor 0.95之前,有一个对象似乎就是这样做的,但它在1.0.0版本时已从Ktor中删除(不幸的是,无法找出原因)

我可以使用ByteArrayContent(见下面的代码)使其工作,但我宁愿找到一个不需要将整个InputStream加载到内存中的解决方案

ByteArrayContent(input.readAllBytes())
这段代码是一个简单的测试用例,模拟了我试图实现的目标:

val file = File("c:\\tmp\\foo.pdf")
val inputStream = file.inputStream()
val client = HttpClient(CIO)
client.call(url) {
      method = HttpMethod.Post
      body = inputStream // TODO: Make this work :(
    }
// [... other code that uses the response below]
如果我遗漏了任何相关信息,请告诉我

谢谢

Ktor 1.2.2中唯一的API(我发现…)可能是发送一个多部分请求,这需要您的接收服务器能够处理,但它确实支持直接输入流

从他们的文档中:

val data: List<PartData> = formData {
    // Can append: String, Number, ByteArray and Input.
    append("hello", "world")
    append("number", 10)
    append("ba", byteArrayOf(1, 2, 3, 4))
    append("input", inputStream.asInput())
    // Allow to set headers to the part:
    append("hello", "world", headersOf("X-My-Header" to "MyValue"))
}
请注意,仍然需要使用InputStreams上的大多数方法关闭inputStream

K或来源:


Kotlin Source:

这是我在Ktor 1.3.0上上传文件到GCP的方法:

client.put<Unit> {
    url(url)
    method = HttpMethod.Put
    body = ByteArrayContent(file.readBytes(), ContentType.Application.OctetStream)
}
client.put{
url(url)
方法=HttpMethod.Put
body=ByteArrayContent(file.readBytes(),ContentType.Application.OctetStream)
}

实现这一点的一种方法是创建的子类,并将其设置到post请求的正文中

一个例子如下所示:

class StreamContent(private val pdfFile:File): OutgoingContent.WriteChannelContent() {
    override suspend fun writeTo(channel: ByteWriteChannel) {
        val readChannel = pdfFile.inputStream().channel
        var copiedBytes: Long
        do {
            copiedBytes = readChannel.copyTo(channel, 1024)
        } while (copiedBytes > 0)
    }
    override val contentType = ContentType.Application.Pdf
    override val contentLength: Long = pdfFile.length()
}


// in suspend function
val pdfFile = File("c:\\tmp\\foo.pdf")
val client = HttpClient()
val result = client.post<HttpResponse>("http://upload.url") {
    body = StreamContent(pdfFile)
}
class StreamContent(private val pdfFile:File):OutgoingContent.WriteChannelContent(){
覆盖暂停乐趣写入(通道:字节写入通道){
val readChannel=pdfFile.inputStream().channel
var copiedBytes:长
做{
copiedBytes=readChannel.copyTo(通道,1024)
}而(复制字节>0)
}
覆盖val contentType=contentType.Application.Pdf
重写val contentLength:Long=pdfFile.length()
}
//暂停运行
val pdfFile=File(“c:\\tmp\\foo.pdf”)
val client=HttpClient()
val结果=客户端。post(“http://upload.url") {
正文=流内容(Pdfile)
}

在内存中读取整个内容是明智的。
class StreamContent(private val pdfFile:File): OutgoingContent.WriteChannelContent() {
    override suspend fun writeTo(channel: ByteWriteChannel) {
        val readChannel = pdfFile.inputStream().channel
        var copiedBytes: Long
        do {
            copiedBytes = readChannel.copyTo(channel, 1024)
        } while (copiedBytes > 0)
    }
    override val contentType = ContentType.Application.Pdf
    override val contentLength: Long = pdfFile.length()
}


// in suspend function
val pdfFile = File("c:\\tmp\\foo.pdf")
val client = HttpClient()
val result = client.post<HttpResponse>("http://upload.url") {
    body = StreamContent(pdfFile)
}