【问题标题】:Converting disrete chunks of Stdin to usable form将离散的标准输入块转换为可用形式
【发布时间】:2016-11-04 04:17:22
【问题描述】:

简单地说,如果用户一次将一大块文本(多行)粘贴到控制台中,我希望能够抓取该块并使用它。

目前我的代码是

val stringLines: List[String] = io.Source.stdin.getLines().toList
doStuff(stringLines)

但是 doStuff 永远不会被调用。我意识到标准输入迭代器没有“结束”,但我如何获得当前的输入?我检查了很多 SO 答案,但没有一个适用于需要整理的多行。我需要同时输入用户输入的所有行,并且它总是以单一数据粘贴的形式出现。

【问题讨论】:

  • 你如何区分慢速输入的两行和作为一个块粘贴的两行?如果您为每个时间戳打上时间戳,您可以确定时差
  • @jwvh 是的,这可行。在一秒钟内或彼此之间到达的文本块应分组,文本只会输入一次或两次,中间有很大的差距。你能建议如何以惯用的方式做到这一点吗?

标签: scala iterator stdin


【解决方案1】:

这是一个粗略的大纲,但它似乎有效。我不得不深入研究 Java Executors,这是我以前没有遇到过的,而且我可能没有正确使用。

您可能想玩弄超时值,但 10 毫秒通过了我的测试。

import java.util.concurrent.{Callable, Executors, TimeUnit}
import scala.util.{Failure, Success, Try}

def getChunk: List[String] = {  // blocks until StdIn has data
  val executor = Executors.newSingleThreadExecutor()
  val callable = new Callable[String]() {
    def call(): String = io.StdIn.readLine()
  }

  def nextLine(acc: List[String]): List[String] =
    Try {executor.submit(callable).get(10L, TimeUnit.MILLISECONDS)} match {
      case Success(str) => nextLine(str :: acc)
      case Failure(_)   => executor.shutdownNow() // should test for Failure type
                           acc.reverse
    }

  nextLine(List(io.StdIn.readLine()))  // this is the blocking part
}

使用非常简单。

val input: List[String] = getChunk

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-02
    • 2013-10-12
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多