Saya baru-baru ini melihat kode untuk membaca seluruh konten InputStream menjadi String di Kotlin, seperti:
// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()
atau seperti ini,
val reader = BufferedReader(InputStreamReader(input))
try {
val results = StringBuilder()
while (true) {
val line = reader.readLine()
if (line == null) break
results.append(line)
}
val inputAsString = results.toString()
} finally {
reader.close()
}
Dan bahkan ini yang terlihat lebih mulus karena menutup otomatis:
val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
val results = StringBuilder()
lines.forEach { results.append(it) }
results.toString()
}
Atau sedikit variasi,
val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()
Kemudian seperti fungsionalitas melipat sesuatu:
val inputString = input.bufferedReader().useLines { lines ->
lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}
Atau variasi buruk yang tidak menutup InputStream
val inputString = BufferedReader(InputStreamReader(input))
.lineSequence()
.fold(StringBuilder()) { buff, line -> buff.append(line) }
.toString()
Tapi mereka semua kikuk dan saya terus menemukan versi yang lebih baru dan berbeda dari yang sama... dan beberapa dari mereka bahkan tidak pernah menutup InputStream. Apa cara yang tidak kikuk (idiomatik) untuk membaca InputStream?
Solusi
Kotlin memiliki ekstensi khusus hanya untuk tujuan ini.
val inputAsString = input.bufferedReader().use { it.readText() } // defaults to UTF-8
Dan dalam contoh ini, Anda dapat memutuskan antara bufferedReader()
atau hanya reader()
. Panggilan ke fungsi Closeable.use()
akan secara otomatis menutup input di akhir eksekusi lambda.
Bacaan lebih lanjut:
Jika Anda sering melakukan hal semacam ini, Anda dapat menulis ini sebagai fungsi ekstensi:
fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
return this.bufferedReader(charset).use { it.readText() }
}
Yang kemudian dapat Anda panggil dengan mudah sebagai:
val inputAsString = input.readTextAndClose() // defaults to UTF-8
Di samping catatan, semua fungsi ekstensi Kotlin yang memerlukan mengetahui charset sudah default ke UTF-8, jadi jika Anda memerlukan pengkodean yang berbeda, Anda perlu menyesuaikan kode di atas dalam panggilan untuk menyertakan pengkodean untuk reader(charset)
atau bufferedReader(charset)
.
Peringatan: Anda mungkin melihat contoh yang lebih pendek:
val inputAsString = input.reader().readText()