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
}
}
}
MJegorovas
10/23/2020, 8:50 AM
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()
}
}
MJegorovas
10/23/2020, 8:51 AM
Any other code improvement suggestions are welcome as well.
b
bezrukov
10/23/2020, 8:55 AM
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
MJegorovas
10/23/2020, 10:29 AM
@bezrukov Thank you!
e
ephemient
10/23/2020, 12:10 PM
if you defined it as
fun InputStream.chunks(): Flow<Chunk>
cold flow instead, you could stop collecting at any point