scala - 如何取消 ConsoleReader.readLine()

标签 scala actor jline

首先,我正在学习 scala 和 Java 世界的新手。
我想创建一个控制台并将此控制台作为可以启动和停止的服务运行。
我能够将 ConsoleReader 运行到 Actor 中,但我不知道如何正确停止 ConsoleReader。
这是代码:

import eu.badmood.util.trace
import scala.actors.Actor._

import tools.jline.console.ConsoleReader

object Main {

  def main(args:Array[String]){
    //start the console
    Console.start(message => {
      //handle console inputs
      message match {
        case "exit" => Console.stop()
        case _ => trace(message)
      }
    })

    //try to stop the console after a time delay
    Thread.sleep(2000)
    Console.stop()

  }

}

object Console {

  private val consoleReader = new ConsoleReader()

  private var running = false

  def start(handler:(String)=>Unit){
    running = true
    actor{
      while (running){
        handler(consoleReader.readLine("\33[32m> \33[0m"))
      }
    }
  }

  def stop(){
    //how to cancel an active call to ConsoleReader.readLine ?
    running = false
  }

}

我也在寻找有关此代码的任何建议!

最佳答案

从输入中读取字符的底层调用是阻塞的。在非 Windows 平台上,它将使用 System.in.read()在 Windows 上它将使用 org.fusesource.jansi.internal.WindowsSupport.readByte .

因此,您面临的挑战是在您想要停止控制台服务时使该阻塞调用返回。见 http://www.javaspecialists.eu/archive/Issue153.htmlIs it possible to read from a InputStream with a timeout?对于一些想法......一旦你弄清楚了,有read返回 -1当您的控制台服务停止时,ConsoleReader认为它已经完成了。您需要 ConsoleReader使用该调用的版本:

  • 如果您在 Windows 上,您可能需要覆盖 tools.jline.AnsiWindowsTerminal并使用 ConsoleReader采用 Terminal 的构造函数(否则 AnsiWindowsTerminal 将直接使用 WindowsSupport.readByte`)
  • 在 unix 上,有一个 ConsoleReader采用 InputStream 的构造函数,您可以提供自己的包装器 System.in

  • 还有一些想法:
  • 有一个scala.Console对象已经,所以为了减少混淆,你的名字不同。
  • System.in是一种独特的资源,因此您可能需要确保只有一个调用者使用 Console.readLine一次。现在start直接调用readLine多个来电者可以调用start .大概控制台服务可以readLine并维护一个处理程序列表。
  • 关于scala - 如何取消 ConsoleReader.readLine(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6723047/

    相关文章:

    scala - SBT 多项目找不到 logback 扩展

    scala - 如何在 sbt 测试中仅显示失败的测试?

    uml - 我可以在用例中扩展 actor 吗?

    java - zookeeper 客户端不向 CLI 提供 "jline support is disabled"消息

    Eclipse - 将通用项目转换为 Scala 项目

    scala - akka中的Actor创建错误

    concurrency - LMAX 的颠覆者模式如何运作?

    scala - Akka Actor 、 future 和闭包

    java - jline 在底部保持提示

    java - 如何使用 Java ProcessBuilder API 运行交互式 bash?