加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 从批处理文件的进程中读取InputStream会跳到下一行

发布时间:2020-12-15 08:47:31 所属栏目:Java 来源:网络整理
导读:我正在尝试使用Runtime.exec()运行批处理文件,然后将其InputStream输出到JTextArea.我有什么作品,但只是部分.批处理文件运行会发生什么,但如果它执行除“echo”之外的命令,该命令会立即终止并执行下一行.例如,假设我尝试运行这样一个简单的批处理文件: @ech
我正在尝试使用Runtime.exec()运行批处理文件,然后将其InputStream输出到JTextArea.我有什么作品,但只是部分.批处理文件运行会发生什么,但如果它执行除“echo”之外的命令,该命令会立即终止并执行下一行.例如,假设我尝试运行这样一个简单的批处理文件:

@echo off
echo hello. waiting 5 seconds.
timeout /t 5 /nobreak > NUL
echo finished. goodbye.

批处理文件执行,JTextArea说

hello. waiting 5 seconds.
finished. goodbye.

但它不会在中间等待5秒钟.

我无法弄清楚为什么这样做.这是我用来运行批处理文件并读取其InputStream的内容.

private class ScriptRunner implements Runnable {
private final GUI.InfoGUI gui; // the name of my GUI class
private final String script;

public ScriptRunner(final GUI.InfoGUI gui,final File script) {
    this.gui = gui;
    this.script = script.getAbsolutePath();
}

@Override
public void run() {
    try {
        final Process p = Runtime.getRuntime().exec(script);
        StreamReader output = new StreamReader(p.getInputStream(),gui);
        Thread t = new Thread(output);
        t.start();
        int exit = p.waitFor();
        output.setComplete(true);
        while (t.isAlive()) {
            sleep(500);
        }
        System.out.println("Processed finished with exit code " + exit);
    } catch (final Exception e) {
        e.printStackTrace();
    }
}

}
private class StreamReader implements Runnable {
private final InputStream is;
private final GUI.InfoGUI gui;

private boolean complete = false;

public StreamReader(InputStream is,GUI.InfoGUI gui) {
    this.is = is;
    this.gui = gui;
}

@Override
public void run() {
    BufferedReader in = new BufferedReader(new InputStreamReader(is));
    try {
        while (!complete || in.ready()) {
            while (in.ready()) {
                gui.setTextAreaText(in.readLine() + "n");
            }
            sleep(250);
        }
    } catch (final Exception e) {
        e.printStackTrace();
    } finally {
            try {
                in.close();
        } catch (final Exception e) {
                e.printStackTrace();
    }
}

public void setComplete(final boolean complete) {
    this.complete = complete;
}

}
public void sleep(final long ms) {
try {
    Thread.sleep(ms);
} catch (final InterruptedException ie) {
}
}

我知道我的代码非常混乱,我确信它包含语法错误.

感谢您提供的任何帮助!

解决方法

您正在创建一个进程,但您没有从其标准错误流中读取.该过程可能是将消息写入其标准错误以告诉您存在问题,但如果您没有读取其标准错误,则无法读取这些消息.

你有两个选择:

>由于您已经有一个从流中读取的类(StreamReader),将其中一个连接到进程的标准错误流(p.getErrorStream())并在另一个Thread中运行它.当对p.waitFor()的调用返回时,您还需要在错误StreamReader上调用setComplete,并等待运行它的Thread死掉.
>将Runtime.getRuntime().exec()的使用替换为ProcessBuilder.此类是Java 5中的新增功能,它提供了另一种运行外部进程的方法.在我看来,它对Runtime.getRuntime().exec()的最显着改进是将进程的标准错误重定向到其标准输出的能力,因此您只能读取一个流.

我强烈建议选择第二个选项并选择将进程的标准错误重定向到其标准输出.

我拿了你的代码并换了一行

final Process p = Runtime.getRuntime().exec(script);

final ProcessBuilder pb = new ProcessBuilder(script);
        pb.redirectErrorStream(true);
        final Process p = pb.start();

另外,我没有你的GUI代码,所以我把进程的输出写入System.out.

当我运行你的代码时,我得到以下输出:

hello. waiting 5 seconds.
ERROR: Input redirection is not supported,exiting the process immediately.
finished. goodbye.
Processed finished with exit code 0

如果您看到该错误消息,您可能已经知道有一些事情发生了超时命令.

顺便说一下,我在你的一条评论中注意到ughzan建议的命令都没有奏效.我用ping -n 5 127.0.0.1>替换了超时行. NUL和脚本按预期运行.我无法重现这个问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读