Best way to translate this java code into kotlin

2020-03-24 05:51发布

问题:

URL url = new URL(urlSpec);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
InputStream in = connection.getInputStream();
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) > 0) {
    out.write(buffer, 0, bytesRead);
}
out.close();

I am especially curious about this part

while(bytesRead = in.read(buffer))

We know that asigements are treated as statements in kotlin while in java they are treated as expressions, so this construct is only possible in java.

What is best way to translate this java code into kotlin?

回答1:

Instead of translating the code literally, make use of Kotlin's stdlib which offers a number of useful extension functions. Here's one version

val text = URL(urlSpec).openConnection().inputStream.bufferedReader().use { it.readText() }

To answer the original question: You're right, assignments are not treated as expressions. Therefore you will need to separate the assignment and the comparison. Take a look at the implementation in the stdlib for an example:

public fun Reader.copyTo(out: Writer, bufferSize: Int = DEFAULT_BUFFER_SIZE): Long {
    var charsCopied: Long = 0
    val buffer = CharArray(bufferSize)
    var chars = read(buffer)
    while (chars >= 0) {
        out.write(buffer, 0, chars)
        charsCopied += chars
        chars = read(buffer)
    }
    return charsCopied
}

Source: https://github.com/JetBrains/kotlin/blob/a66fc9043437d2e75f04feadcfc63c61b04bd196/libraries/stdlib/src/kotlin/io/ReadWrite.kt#L114



回答2:

You could use apply block to execute the assignment:

val input= connection.getInputStream();
var bytesRead = 0;
val buffer = ByteArray(1024)
while (input.read(buffer).apply { bytesRead = this } > 0) {
    out.write(buffer, 0, bytesRead);
}


回答3:

You could use something like this

This operation may be little heavy as a function is created each iteration.

val url = URL("urlSpec")
val connection = url.openConnection() as HttpURLConnection
val `in` = connection.inputStream
val buffer = ByteArray(1024)
var bytesRead: Int? = null
while ({ bytesRead = `in`.read(buffer); bytesRead }() != null) {
        out.write(buffer, 0, bytesRead!!)
}
out.close()


标签: kotlin