is there a nicer way of writing this? ```inputStr...
# codereview
t
is there a nicer way of writing this?
Copy code
inputStream.apply { skip(from.toLong()) }.use {
    var bytesLeft = bytesToWrite
    while (bytesLeft != 0) {
        val read = it.read(buffer, 0, Math.min(buffer.size, bytesLeft))
        outputStream.write(buffer, 0, read)
        bytesLeft -= read
    }
}
m
since Java 9, InputStream has the method
transferTo(OutputStream)
https://docs.oracle.com/javase/9/docs/api/java/io/InputStream.html#transferTo-java.io.OutputStream- So you can write:
Copy code
inputStream.apply { 
    skip(from.toLong()) 
}.transferTo(outputStream)
This works well if both are simple In/Out streams, otherwise if you’re dealing with files (FileInputStream/FileOutputStream) you should prefer
Files.copy
as it will be faster.
t
i'd probably get rid of the
.apply
and move the skip into the use block
t
thanks @Matteo Mirk, unfortunately i'm targeting java8
m
oh… that’s really unfortunate! 😞
Anyway it’s still worth try copying the code from OpenJDK 9 and create an extension function
👍 1
t
🤔
sure, why not
m
Or use your implementation, as you please, but I would encapsulate it into an ext fun for readability
🆒
t
i trust openjdk more
👍 2
t
kotlin has a copyTo ext function already as well
message has been deleted
Copy code
inputStream.use {
  it.skip(from.toLong())
  it.copyTo(outputStream)
}
t
can you limit the bytes to write in it?
i don't want to write the whole inputstream
t
ah not with this one. but maybe there is something like a .subset(drop, truncate) to wrap the input stream. that way you can compose it rather than handwriting
m
kotlin has a copyTo ext function already as well
Ohh cool didn’t know it! Of course it has one 😉
t
big detail I missed was the "bytesToWrite" arg 😕 maybe a nice raw
Sequence<Byte>
so you could do something like
.takeWhile
(if that is a thing, or maybe I just am stuck in reactivex thinking too far?)
I dunno, overthinking, probably just wrap up what you have in an ext fun , drop the apply so if skip pukes you don't leak the stream?
t
Copy code
private fun InputStream.copyTo(outputStream: OutputStream, from: Int, to: Int, buffer: ByteArray = ByteArray(1024)) = this.use {
    it.skip(from.toLong())
    var bytesLeft = to
    while (bytesLeft != 0) {
        val read = it.read(buffer, 0, Math.min(buffer.size, bytesLeft))
        outputStream.write(buffer, 0, read)
        bytesLeft -= read
    }
}
❤️ 1
reads a lot nicer, thank you
wish i could get rid of that while, but i'll live
t
one other nit, which I would expect intellij to be screaming about.
Math.min
looks from java but kotlin has a top level
min
I thought?
t
it suggests
buffer.size.coerceAtMost(bytesLeft))
but i found that much harder to read..
t
I agree, feels like prioritizing an extension function just to use an extension function. plus min(x,y) etc are so common everywhere 🤔