Home > database >  How can I convert Stream<Byte> to InputStream
How can I convert Stream<Byte> to InputStream

Time:10-20

I have java.util.stream.Stream<Byte> in Java/Kotlin(jvm).

How can I convert java.util.stream.Stream<Byte> to java.io.InputStream without keeping each buffer in memory.

I can do this conversion by

fun convertToInputStream(byteStream: Stream<Byte>) = ByteArrayInputStream(byteStream.collect(Collectors.toList()).toByteArray())

In my example I will get an OutOfMemoryError if I use a large limit because it creates a large byte[] in memory

import java.io.ByteArrayInputStream
import java.io.File
import java.util.stream.Collectors
import java.util.stream.IntStream
import java.util.stream.Stream

fun convertToInputStream(byteStream: Stream<Byte>) = ByteArrayInputStream(byteStream.collect(Collectors.toList()).toByteArray())


fun main() {

    val file = File("/tmp/data.txt")
    val inputStream = convertToInputStream(
        IntStream.iterate(1) { 65   it % 3 }.limit(1000000000).mapToObj { it.toByte() }
    )
    inputStream.copyTo(file.outputStream())
}

CodePudding user response:

You could implement it with something like this:

fun main() {
    val stream = Stream.of<Byte>(10, 15, -50, 20, 50)

    val buf = ByteArrayOutputStream()
    stream.asInputStream().transferTo(buf)

    val bytes = buf.toByteArray() // [10, 15, -50, 20, 50]
}

fun Stream<Byte>.asInputStream() = object : InputStream() {
    private val iter = iterator()

    override fun read() = if (iter.hasNext()) iter.next().toUByte().toInt() else -1
}

You would probably need to override more methods to improve performance or provide more functionality, like for example closing the stream.

Also, note that I didn't test this code thoroughly.

  • Related