Kotlin 链接来自不同输入流的多个序列?

2023-12-15

假设我想解析这样的大文件:

val iStream = MyFile::class.java
    .getResourceAsStream("largeFile.txt")

iStream.bufferedReader(Charsets.UTF_8).useLines { lines ->
    lines.filterNot { it.startsWith("#") }
    // parseing
    .toSet()
}

但是如果我想将大文件拆分为多个较小的文件,如何链接序列?

例如 :

val seq1 = MyFile::class.java.getResourceAsStream("file1.txt")
    .use { it.bufferedReader(Charsets.UTF_8).lineSequence() }
val seq2 = MyFile::class.java.getResourceAsStream("file2.txt")
    .use { it.bufferedReader(Charsets.UTF_8).lineSequence() }

sequenceOf(seq1, seq2).flatten()
  .filterNot { it.startsWith("#") }
  // parsing
  .toSet()

它会抛出java.io.IOException: Stream closed,这是合理的,因为解析是在scope of the use block.

如何解决问题?

我知道可能有一些nesting解决方案(嵌套useLines...),但我认为那很丑陋。还有其他的吗flat解决方案?


你可以颠倒你的逻辑。重要的是,一切都在use否则,正如您所知,这将不起作用。

一种这样的 ~invert 可能看起来像:

setOf("file1.txt", "file2.txt")
  .map { MyFile::class.java.getResourceAsStream(it) }
  .flatMap {
    it.use {
      it.bufferedReader(Charsets.UTF_8)
        .lineSequence()
        .filterNot { it.startsWith("#") }
        .toSet()
    }
  }

或者,如果您想从外部传递链转换或过滤器,可能类似于:

val handleLine : (Sequence<String>) -> Sequence<String> = {
  it.filterNot { it.startsWith("#") }
  // .map { ... whatever }
}
setOf("file1.txt", "file2.txt")
  .map { MyFile::class.java.getResourceAsStream(it) }
  .flatMap {
    it.use {
      handleLine(it.bufferedReader(Charsets.UTF_8).lineSequence())
        .toSet()
    }
  }

另一种选择是打开流,省略use最后自己关闭它们,正如 @MarkoTopolnik 在评论中指出的那样:

val inputStreams = sequenceOf("file1.txt", "file2.txt")
  .map { MyFile::class.java.getResourceAsStream(it) }

inputStreams.flatMap { it.bufferedReader(Charsets.UTF_8).lineSequence() }
  .filterNot { it.startsWith("#") }
  .toSet()

然后使用:

inputStreams.forEach(InputStream::close) // but this will fail on the first error...

或“安全”方式:

inputStreams.forEach { try { it.close() } catch (e: Exception) { e.printStackTrace() } }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kotlin 链接来自不同输入流的多个序列? 的相关文章

随机推荐