1

So say I have a stream being returned from a socket connection. The stream is being returned terminated with '\0' but in kotlin I can't seem to get this to work the same way. The code below is in Java and I am probably just over looking something simple.

public final String readUpToNull(InputStream inputStream) throws IOException {
    StringBuilder builder = new StringBuilder();
    char ch;
    while ((ch = (char) inputStream.read()) != '\0') {
        builder.append(ch);
    }
    return builder.toString();
}

If anyone knows how to do this while communicating with a socket with the streams in Kotlin. The other post that is on here is covering reading the full string of text. The socket is returning a longer string delimited by the '\0'. So the issue is I need to be able to load up the first string then the second string.

Example

Server : hello\0 xml stuff all right here\0
Client: read hello
Client: read xml stuff all right here

Example code from kotlinlang.org shows this as a solution using the Java to Kotlin converter. Note that this code does not compile because of the assignment in the while statement.

@Throws(IOException::class)
fun readUpToNull(inputStream:InputStream):String {
    val builder = StringBuilder()
    val ch:Char
    while ((ch = inputStream.read() as Char) != '\u0000')
    {
      builder.append(ch)
    }
    return builder.toString()
}

Here is what I have so far but the this implementation is just hanging up the processes and is locking the unit test for the API call.

fun readUpToNull(stream: InputStream): String {
    val reader = BufferedReader(InputStreamReader(stream))
    val builder = StringBuilder()
    while (true) {
        val characters = reader.readText().toCharArray()
        characters.takeWhile { it != '\u0000' }.forEach { builder.append(it) }
        break
    }
    return builder.toString()
}
Catlin Cox
  • 13
  • 4
  • Possible duplicate of [In Kotlin, how do I read the entire contents of an InputStream into a String?](https://stackoverflow.com/questions/39500045/in-kotlin-how-do-i-read-the-entire-contents-of-an-inputstream-into-a-string) – Andrii Abramov Jun 13 '17 at 14:59
  • We don't know what the format of the data is. If you are reading until you receive a zero *byte*, then read in bytes and check for this zero byte. If you are reading an encoded byte stream for a specific charset then create a proper Reader for that charset and read in and examine individual characters. – President James K. Polk Jun 13 '17 at 16:44
  • I am reading up to the null character of the stream. The stream is coming back as UTF-8 from a tomcat server. – Catlin Cox Jun 13 '17 at 18:48
  • The default charset used by the buffered reader in Kotlin is UTF-8 so not passing the encoding is not what is causing the problem. – Catlin Cox Jun 13 '17 at 18:59

2 Answers2

1

Here's a more-or-less direct translation of your Java code to Kotlin:

fun readUpToNull(inputStream: InputStream): String {
    return buildString {
        while (true) {
            val ch = inputStream.read().toChar()
            if (ch == '\u0000') break
            append(ch)
        }
    }
}
Alexander Udalov
  • 31,429
  • 6
  • 80
  • 66
0

I had a similar issue where I tried to convert a null character terminated string from a ByteArray to a string.

Where the Bytearray looked like this:

[123, 57, 46, 52, 125, 10, 0 , 17, 53, 12] // {9.4}

Where the value 0 represents the null character '\0'. After the null character there's various garbage which I want to ignore.

Since its easy to convert a input stream into array the solution below will work for input streams from sockets.

val inputByteArray : ByteArray = inputStream.readBytes()
val inputString : String = String(inputByteArray).substringBefore('\u0000') // Truncate string after null character