将 InputStream 转换为 Flow

9
我希望您能读取文件内容并为其每一行生成一个流。因此,我需要实现以下签名的函数:
fun InputStream.linesToFlow(): Flow<String>

有没有办法实现这个功能?

2个回答

13

我也找到了以下解决方案:

fun InputStream.linesToFlow() = bufferedReader().lineSequence().asFlow().flowOn(Dispatchers.IO)

6
你可能想在结尾处加上 .flowOn(Dispatchers.IO),以确保它不会意外地阻塞一些有用的线程。 - Roman Elizarov
我在 Kotlin 的 Slack 中也看到了这个建议。但我想为此写一个更好的说明。你能描述一下为什么需要将其作为文档在这里呈现吗? - alisabzevari
3
创建一个 Scratch 项目,尝试运行这个 Gist 中的代码:https://gist.github.com/elizarov/311b646c2fbf5fe19768fac3f21fe109 现在,添加 .flowOn(Dispatchers.IO),看看会有什么不同。 - Roman Elizarov
@RomanElizarov我使用了.flowOn运行了gist,但是没有看到任何区别。我应该看到什么?此外,.flowOn似乎很关键,因为它将流放在单独的(IO)线程上,从主线程中取出。如果我弄错了,请提供一个链接让我学习并弄对。最后,yield()的目的是什么?这只是为了回到主(原始)线程吗? - pajato0

-2

你可以做到这个

fun InputStream.linesToFlow(): Flow<String> = channelFlow<String> {
    reader().forEachLine { line -> 
        offer(line)
    }
}

1
当收集器速度较慢时,它将会丢失行。取一些文本文件,然后尝试执行 File("text.txt").inputStream().use { it.linesToFlow { line -> println(line); delay(1000) } },(正确的解决方案应该每秒打印一行)。 - Roman Elizarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接