Skip to content

Instantly share code, notes, and snippets.

@Malinskiy
Created March 29, 2021 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Malinskiy/d7f138c35467cf64be4825dc6d561c12 to your computer and use it in GitHub Desktop.
Save Malinskiy/d7f138c35467cf64be4825dc6d561c12 to your computer and use it in GitHub Desktop.
class AsyncFileReader(
file: File,
override val coroutineContext: CoroutineContext = Dispatchers.IO
) : CoroutineScope, Closeable {
private val fileChannel = file.inputStream().buffered()
private val bufferChannel: Channel<ByteBuffer> = Channel(capacity = 2)
private var job: Job? = null
fun start() {
job = launch {
while (isActive) {
val byteBuffer = ByteBufferPool.borrow()
when (val read = fileChannel.read(byteBuffer.array())) {
-1 -> {
close()
}
else -> {
byteBuffer.limit(read)
bufferChannel.send(byteBuffer)
}
}
}
}
}
suspend fun <T> read(block: suspend (ByteBuffer?) -> T): T {
return block(bufferChannel.receiveOrNull())
}
override fun close() {
job?.cancel()
fileChannel.close()
bufferChannel.close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment