如何确定BufferedReader的确切状态?

Kid*_*rla 7 java io

我有BufferedReader(生成new BufferedReader(new InputStreamReader(process.getInputStream()))).我对a的概念很陌生,BufferedReader但正如我所看到的,它有三种状态:

  1. 一条线正在等待阅读; 调用bufferedReader.readLine将立即返回此字符串.
  2. 流是开放的,但没有线等待阅读; 调用bufferedReader.readLine将挂起线程,直到一行可用.
  3. 溪流关闭; 调用bufferedReader.readLine将返回null.

现在我想确定状态BufferedReader,以便我可以确定是否可以安全地从中读取而不挂起我的应用程序.基本过程(见上文)众所周知是不可靠的,因此可能已经挂起; 在这种情况下,我不希望我的宿主应用程序挂起.因此我正在实施一种超时.我试图首先使用线程进行此操作,但它变得非常复杂.

呼叫BufferedReader.ready()不会区分上述情况(2)和(3).换句话说,如果ready()返回false,则可能是流刚刚关闭(换句话说,我的底层进程正常关闭),或者可能是底层进程挂起.

所以我的问题是:如何BufferedReader在不实际调用的情况下确定我所处的这三种状态中的哪一种readLine?不幸的是,我不能打电话readLine来检查这个,因为它打开我的应用程序挂起.

我使用的是JDK 1.5版.

Kid*_*rla 3

最后我找到了解决这个问题的方法。这里的大多数答案都依赖于线程,但正如我之前指定的,我正在寻找不需要线程的解决方案。然而,我的基础是过程。我发现,如果输出(称为“输入”)和错误流都为空并关闭,则进程似乎会退出。如果你仔细想想,这是有道理的。

因此,我只是轮询输出和错误流,并尝试确定进程是否已退出。下面是我的解决方案的粗略副本。

public String readLineWithTimeout(Process process, long timeout) throws IOException, TimeoutException {
  BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
  BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  boolean finished = false;
  long startTime = 0;
  while (!finished) {
    if (output.ready()) {
      return output.readLine();
    } else if (error.ready()) {
      error.readLine();
    } else {
      try {
        process.exitValue();
        return null;
      } catch (IllegalThreadStateException ex) {
        //Expected behaviour
      }
    }
    if (startTime == 0) {
      startTime = System.currentTimeMills();
    } else if (System.currentTimeMillis() > startTime + timeout) {
      throw new TimeoutException();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)