I have a kotlinx io Source. I would like to read c...
# io
e
I have a kotlinx io Source. I would like to read chunks of size N and only get a smaller chunk if it’s the end of the file. readAtMostTo looks like what I want, but it’s not guaranteed to read the full chunk size
In particular, looks like if you hit the 8192 buffer size and it doesn’t line up with your chunk size exactly, you’ll get a partial chunk even if the Source still has more data
Do I just wrap readAtMostTo in a while loop? Gross
Copy code
private fun readChunk(from: Source, buffer: Buffer, chunkSize: Long): ByteArray? {
        var numBytesRead = 0L
        while (numBytesRead != -1L && numBytesRead != chunkSize && !from.exhausted()) {
            val read = from.readAtMostTo(sink = buffer, byteCount = chunkSize - numBytesRead)
            if (read == -1L) {
                return null
            }
            numBytesRead += read
        }
        if (from.exhausted() && numBytesRead == 0L) {
            return null
        }
        return buffer.readByteArray()
    }
Probably could clean that up a bit more but it works ¯\_(ツ)_/¯
f
Hey!
Source
has readTo function which reads exactly N bytes into a sink (which could be a
Buffer
). And if all you need is an array of bytes, readByteArray(byteCount: Int) should also read exactly
byteCount
bytes. You can always combine them with Source.request(byteCount: Long) to make sure that the source has the whole chunk. Something like:
Copy code
private fun readChunk(from: Source, chunkSize: Long): ByteArray? {
   require(chunkSize in 0..Int.MAX_VALUE)

   return when {
      from.request(chunkSize) -> from.readByteArray(chunkSize.toInt())
      from.exhausted() -> null
      else -> from.readByteArray()
   }
}
🎉 1
e
readByteArray(int) doesn’t work for the end of file case, sadly (throws an exception)
Will look at the others, thx!