Is there a way to split/buffer a ByteReadChannel? ...
# ktor
q
Is there a way to split/buffer a ByteReadChannel? My use case is downloading a file from a http URL on GET request and then streaming it to the client as as well as a local file.
e
Hi @Quy D X Nguyen, it looks like: https://api.ktor.io/1.3.2/io.ktor.util/split.html
q
So this code does not respond, but the commented line works fine.
Copy code
get("/") {
	call.respondBytesWriter(ContentType.defaultForFileExtension(".jpg")) {
		client.get<HttpStatement>("<https://chandra.harvard.edu/photo/2017/arp299/arp299_4k.jpg>").execute { response: HttpResponse ->
			//response.receive<ByteReadChannel>().joinTo(this, false)
			val (channelResponse, channelFile) = response.receive<ByteReadChannel>().split(this@embeddedServer)
			
			channelFile.joinTo(File("image").writeChannel(), true)
			channelResponse.joinTo(this, false)
		}
	}
}
e
Could you move one of your consumers to
launch { }
? The channels should be consumed simultaneously.
q
I'm not too familiar with coroutines, so I don't know where you want this
launch{}
call
I edited my sample with me also consuming the channelFile, but this still does not work.
Does ktor have a coroutinecontext for blocking IO?
Apparently, the default
<http://Dispatchers.IO|Dispatchers.IO>
context for
writeChannel()
does not play well with
split()
. Do you know why?
Copy code
val fileSave = newFixedThreadPoolContext(8, "fileSave")
...
                        channelFile.joinTo(File("image").writeChannel(fileSave), true)
This works,
It appears that the
split()
gums everything up, but they work individually