我试图以这种方式从Ktor文件发送一个本地保存的文件(90 to )。
val client = HttpClient(CIO)
val response: HttpResponse = client.post("http://localhost:8080/upload") {
setBody(MultiPartFormDataContent(
formData {
append("description", "Ktor logo")
append("image", File("ktor_logo.png").readBytes(), Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"ktor_logo.png\"")
})
},
boundary = "WebAppBoundary"
)
)
onUpload { bytesSentTotal, contentLength ->
println("Sent $bytesSentTotal bytes from $contentLength")
}
}
也没有得到这个错误
FATAL EXCEPTION: DefaultDispatcher-worker-2
PID: 8152
java.lang.OutOfMemoryError: Failed to allocate a 4112 byte allocation with 1424 free bytes and 1424B until OOM, max allowed footprint 100663296, growth limit 100663296
at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:54)
at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:49)
at java.nio.ByteBuffer.allocate(ByteBuffer.java:281)
at io.ktor.utils.io.bits.DefaultAllocator.alloc-gFv-Zug(MemoryFactoryJvm.kt:41)
at io.ktor.utils.io.core.DefaultBufferPool.produceInstance(BufferFactory.kt:58)
at io.ktor.utils.io.core.DefaultBufferPool.produceInstance(BufferFactory.kt:51)
at io.ktor.utils.io.pool.DefaultPool.borrow(DefaultPool.kt:51)
at io.ktor.utils.io.core.internal.ChunkBuffer$Companion$Pool$1.borrow(ChunkBuffer.kt:133)
at io.ktor.utils.io.core.internal.ChunkBuffer$Companion$Pool$1.borrow(ChunkBuffer.kt:128)
at io.ktor.utils.io.core.Output.appendNewChunk(Output.kt:102)
at io.ktor.utils.io.core.Output.prepareWriteHead(Output.kt:354)
at io.ktor.utils.io.core.internal.UnsafeKt.prepareWriteHead(Unsafe.kt:57)
at io.ktor.utils.io.ByteBufferChannel.readRemainingSuspend(ByteBufferChannel.kt:3689)
at io.ktor.utils.io.ByteBufferChannel.access$readRemainingSuspend(ByteBufferChannel.kt:24)
at io.ktor.utils.io.ByteBufferChannel$readRemainingSuspend$1.invokeSuspend(Unknown Source:16)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@29cc6a1, Dispatchers.IO]
据我所知,这是因为readBytes()
。
是否有任何方法可以使用Ktor以表单数据的形式部分发送大文件并避免此错误。
UPD 1
也尝试过,同样的错误
appendInput(
"MY_KEY",
Headers.build {
headers.forEach { h ->
this.append(h.first, h.second) // Content-Disposition and Content-Type here
}
},
file.length()
){
file.inputStream().asInput()
}
发布于 2022-09-13 13:19:50
您可以使用InputProvider
按块读取文件:
formData {
// ...
val file = File("ktor_logo.png")
append(
"image",
InputProvider(file.length()) { file.inputStream().asInput() },
Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"ktor_logo.png\"")
}
)
},
https://stackoverflow.com/questions/73703274
复制相似问题