了解 JSch 命令输出读取问题
在您提供的使用 JSch 的 Java 代码中,您遇到了程序在尝试读取时挂起的情况来自用于捕获命令输出的读取器流。本文解释了此问题的原因并提供了解决方案。
问题分析
根本问题是由于没有持续消耗执行命令产生的输出而产生的。 JSch 命令将输出累积在内部缓冲区中,如果缓冲区在被使用之前已满,则可能会导致死锁,命令会挂起等待缓冲区被清除。
解决方案
要解决此问题,您必须连续读取命令的标准输出和标准错误流,即使在等待命令完成时也是如此。这可确保输出缓冲区永远不会填满并且命令不会挂起。
示例代码
以下是包含此解决方案的代码的扩展版本:
<code class="java">ChannelExec channel = (ChannelExec)session.openChannel("exec"); channel.setCommand(...); // Set the command to execute ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream(); InputStream in = channel.getInputStream(); InputStream err = channel.getExtInputStream(); channel.connect(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; outputBuffer.write(tmp, 0, i); } while (err.available() > 0) { int i = err.read(tmp, 0, 1024); if (i < 0) break; errorBuffer.write(tmp, 0, i); } if (channel.isClosed()) { if ((in.available() > 0) || (err.available() > 0)) continue; System.out.println("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } System.out.println("output: " + outputBuffer.toString("UTF-8")); System.out.println("error: " + errorBuffer.toString("UTF-8")); channel.disconnect();</code>
在此示例中,while 循环不断读取输出流(in 和 err),同时监视命令的状态 (channel.isClosed())。这可以确保捕获所有输出,即使命令生成大量数据也是如此。
以上是为什么我的 JSch 命令在读取输出时挂起?的详细内容。更多信息请关注PHP中文网其他相关文章!