Is `offset` variable in this method safe to use in...
# coroutines
m
Is
offset
variable in this method safe to use in multiple threads?
Copy code
suspend fun InputStream.readByChunks(
    fileSize: Long,
    chunkSize: Int,
    block: suspend (bytes: ByteArray, offset: Long) -> Unit
) {
    var offset = 0L

    this.buffered().use { input ->
        while (offset != fileSize) {
            val buffer = if (offset + chunkSize < fileSize) {
                ByteArray(chunkSize)
            } else {
                ByteArray((fileSize - offset).toInt())
            }

            val read = input.read(buffer)
            block(buffer, offset)
            offset += read
        }
    }
}
Use case:
Copy code
val semaphore = Semaphore(4)

fileInputStream.readByChunks(size, BYTE_SPLIT_SIZE_SERVER) { bytes, offset ->
    semaphore.acquire()
    launch(Dispatchers.Default) {
        val encryptedBytes = encrypt(bytes, password)
        val storeResult = server.storeFileContent(encryptedBytes, itemId, offset)
        if (storeResult.isError()) {
            // Cancel reading and report about unsuccessful operation
        }

        progress.updatePrimaryProgress()
        semaphore.release()
    }
}
Any other code improvement suggestions are welcome as well.
b
yes offset is passed by value (so it's copied), if it's compiled as primitive. If it complied as Long object, it's safe as well because it's immutable.
m
@bezrukov Thank you!
e
if you defined it as
fun InputStream.chunks(): Flow<Chunk>
cold flow instead, you could stop collecting at any point