InputStream replace


#1

Hello,
I’m new to Kotlin and have a question.

Let’s say I have an InputStream of bytes.
I need to find a startByte
then replace specific combinations of two bytes with one byte,
until i find the stop byte
and then go on with the InputStream.
I’m not sure how to do it, read byte by byte and cache a matching byte,
or use a larger byteArray buffer?

What technics are the best for those problems in Kotlin?

As example with a buffer (76 start byte, 54 end byte):

val byteA = byteArrayOf(22,23,24,76,1,2,3,4,54,1,5,3,76,1,2,5,6,54)
val bytesTrimmed = byteA.dropWhile {it !=76.toByte()}.takeWhile { it != 54.toByte()}

This gives me the first byte range where I need to replace specific combinations of two bytes with one byte, let’ say 1,2 with 42 and 5,6 with 99 and then go on with the stream.


#2

I don’t think it is a kotlin-specific problem. There are a lot of different ways to do so and the choice depends on task specifics. The quickest way is to read everything into string and than replace all occurrences via String::replace, but it it has the worst performance. If you want to work with large streams on JVM, you probably will want to implements some variant of [FilterInputStream] (https://docs.oracle.com/javase/9/docs/api/java/io/FilterInputStream.html) with internal buffer. In kotlin you also can use sequence instead of stream, but the resulting object will be of type Sequence instead of InputStream. So you need to decide first, where you want to use it.


#3

You basically have a (very simple) Markov chain to apply on a sequence of bytes with some buffering (when you have found the first byte but don’t know the second). Streams are quite appropriate as solution there as it is straightforward to allow further use. Just remember that normally you want a buffered stream (unless you are reading from memory already) as individual byte access to files/network is far from optimal.