Kotlin has a specific extension just for this purpose.
The simplest:
val inputAsString = input.bufferedReader().use { it.readText() } // defaults to UTF-8
And in this example, you could decide between bufferedReader() or just reader(). The call to the function Closeable.use() will automatically close the input at the end of the lambda's execution.
Further reading:
If you do this type of thing a lot, you could write this as an extension function:
fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
return this.bufferedReader(charset).use { it.readText() }
}
Which you could then call easily as:
val inputAsString = input.readTextAndClose() // defaults to UTF-8
On a side note, all Kotlin extension functions that require knowing the charset already default to UTF-8, so if you require a different encoding you need to adjust the code above in calls to include encoding for reader(charset) or bufferedReader(charset).
Warning: You might see examples that are shorter:
val inputAsString = input.reader().readText()
But these do not close the stream. Make sure you check the API documentation for all of the IO functions you use to be sure which ones close and which do not. Usually, if they include the word use (such as useLines() or use()) they close the stream after. An exception is that File.readText() differs from Reader.readText() in that the former does not leave anything open and the latter does indeed require an explicit close.
See also: Kotlin IO related extension functions
Kotlin has a specific extension just for this purpose.
The simplest:
val inputAsString = input.bufferedReader().use { it.readText() } // defaults to UTF-8
And in this example, you could decide between bufferedReader() or just reader(). The call to the function Closeable.use() will automatically close the input at the end of the lambda's execution.
Further reading:
If you do this type of thing a lot, you could write this as an extension function:
fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
return this.bufferedReader(charset).use { it.readText() }
}
Which you could then call easily as:
val inputAsString = input.readTextAndClose() // defaults to UTF-8
On a side note, all Kotlin extension functions that require knowing the charset already default to UTF-8, so if you require a different encoding you need to adjust the code above in calls to include encoding for reader(charset) or bufferedReader(charset).
Warning: You might see examples that are shorter:
val inputAsString = input.reader().readText()
But these do not close the stream. Make sure you check the API documentation for all of the IO functions you use to be sure which ones close and which do not. Usually, if they include the word use (such as useLines() or use()) they close the stream after. An exception is that File.readText() differs from Reader.readText() in that the former does not leave anything open and the latter does indeed require an explicit close.
See also: Kotlin IO related extension functions
【Method 1 | Manually Close Stream】
private fun getFileText(uri: Uri):String {
val inputStream = contentResolver.openInputStream(uri)!!
val bytes = inputStream.readBytes() //see below
val text = String(bytes, StandardCharsets.UTF_8) //specify charset
inputStream.close()
return text
}
inputStream.readBytes()requires manually close the stream: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/read-bytes.html
【Method 2 | Automatically Close Stream】
private fun getFileText(uri: Uri): String {
return contentResolver.openInputStream(uri)!!.bufferedReader().use {it.readText() }
}
You can specify the charset inside
bufferedReader(), default isUTF-8: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/buffered-reader.htmlbufferedReader()is an upgrade version ofreader(), it is more versatile: How exactly does bufferedReader() work in Kotlin?use()can automatically close the stream when the block is done: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.html
Kotlin has an extension for String to convert directly.
val inputStream: InputStream = myString.byteInputStream()
The argument on byteInputStream is defaulted to charset: Charset = Charsets.UTF_8.
You can look at the extension by writing it and then cmd+click on it or in the package kotlin.io file IOStream.kt
Relying on the Java version is not wrong, but rather using a more kotlin idiomatic way when possible
val myString = "text"
val targetStream: InputStream = ByteArrayInputStream(initialString.toByteArray())
Pst. If you copy some java code, for example:
String myString = "text";
InputStream targetStream = new ByteArrayInputStream(myString.getBytes());
Android Studio will popup "Clipboard content seems to be Java code. Do you want to convert it to Kotlin?
The easiest way is to use
File("aaa").readBytes()
That one will read the whole file into the ByteArray. But you should carefully know you have enough RAM in the heap to do so
The ByteArray can be created via ByteArray(100) call, where 100 is the size of it
For the RandomAccessFile, it is probably better to use at the readFully function, which reads exactly the requested amount of bytes.
The classic approach is possible to read a file by chunks, e.g.
val buff = ByteArray(1230)
File("aaa").inputStream().buffered().use { input ->
while(true) {
val sz = input.read(buff)
if (sz <= 0) break
///at that point we have a sz bytes in the buff to process
consumeArray(buff, 0, sz)
}
}
I found this worked nicely:
fun File.chunkedSequence(chunk: Int): Sequence<ByteArray> {
val input = this.inputStream().buffered()
val buffer = ByteArray(chunk)
return generateSequence {
val red = input.read(buffer)
if (red >= 0) buffer.copyOf(red)
else {
input.close()
null
}
}
}
Use it like this.
file.chunkedSequence(CHUNK_SIZE).forEach {
// Do something with `it`
}
Not an exact match to your question but this is the question that came up when I was looking to chunk a file into a sequence of byte arrays.