首页 > 解决方案 > 如何在一个协程中读取文件并在另一个协程中打印行?

问题描述

我正在努力适应 Kotlin/协程。我目前的目标是在一个协程中读取文本文件,并通过 Channel 发出每一行以在另一个协程中打印。这是我到目前为止所拥有的:

fun main() = runBlocking {

    val ch = Channel<String>()

    launch {
        for (msg in ch) {
            println(msg.length)
        }
    }

    launch {
        File("file.txt").forEachLine {
            ch.send(it)
        }
    }
}

希望这表明了我的意图,但它不能编译,因为你不能send从传递给的 lambda 调用挂起函数 () forEachLine。在 Golang 中,一切都是同步建模的,所以我只会在 goroutine 中运行它并send会阻塞,但 Kotlin 似乎有一个较低级别的并发模型。实现这一目标的规范方法是什么?

如果有帮助,我的最终目标是通过标准输出读取子进程发出的 JSON 事件。我将在每一行上都有一个单独的 JSON 对象,并且需要分别解析和处理每个对象。

标签: kotlinkotlin-coroutines

解决方案


这是迄今为止我能想到的最好的。它似乎有效,但我觉得必须有一种更惯用的方式来实现这一点。

fun main() = runBlocking {

    val ch = Channel<String>()

    launch {
        for (msg in ch) {
            println(msg.length)
        }
    }

    launch {
        val istream = File("file.txt").inputStream()
        val buf = ByteArray(4096)

        while (true) {
            val n = istream.read(buf)

            if (n == -1) {
                break
            }

            val msg = buf.sliceArray(0..n-1).toString(Charsets.UTF_8)
            ch.send(msg)
        }

        ch.close()
    }
}

推荐阅读