1

我正在制作一个能够直接在其中运行 java 编译器和 jvm 的程序(不要问我为什么要重新发明轮子,如果您的回复没有帮助,请保存它,我已经很沮丧花费几个小时的解决方案不起作用!)。到目前为止,我已经设法跟踪每当我在我的 textField 中输入以 java 开头的内容时,它实际上会包装文本并像这样运行它:

    if(String.valueOf(object).startsWith("java")){
        try{
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec(String.valueOf(object));
        }
        catch(Exception e){gsc.mainWindow.printf("error");}

考虑gsc.mainWindow.printf(...);我对 JFrame 中的 JTextArea 的输出。

我现在管理的是运行命令,但是任何失败我都可以将它直接打印到我的输出中。我知道这已经被回答过很多次了,阅读了大约 10 种方法来做到这一点,但它们都没有奏效或无法理解到我可以运行它的程度。我需要代码足够简单,因为这必须输出进程将在默认系统的控制台(cmd,终端)中写入的内容,然后停止(我认为这可能是一个方法调用)。我对这种东西很不满意,即使是多线程解决方案也能满足我的需求,真的没什么太专业的,我只需要它就能工作。您需要的任何信息,请询问!提前致谢!:)

4

1 回答 1

4

我不知道您是否想阅读本文,但您知道,在 Java 世界中,您应该始终在实现自己的解决方案之前寻找解决方案。而常见问题的解决方案,大多数时候,来自Apache Commons或其他 Apache 项目。说除了你的解决方案之外的所有东西都不起作用或对你来说太复杂只会花费你的时间和金钱(最终还有你的工作)。

Apache Commons Exec是您更快、更轻松地解决问题所需的工具。

- - 编辑 - -

这是一些如何捕获子进程输出的代码。有一个专门针对它的类PumpStreamHandler

DefaultExecutor exec = new DefaultExecutor();
PumpStreamHandler streamHandler = new PumpStreamHandler();
exec.setStreamHandler(streamHandler);

CommandLine commandline = CommandLine.parse(command);  //where command is your command line
exec.execute(commandline);

---- 编辑 2 ----

这是您要使用以下命令捕获消息的复制粘贴解决方案OutputStream

public abstract class LogOutputStream extends OutputStream {

protected static final String LINE_SEPERATOR = System.getProperty("line.separator");
public static final int DEFAULT_BUFFER_LENGTH = 2048;

protected boolean hasBeenClosed = false;
protected byte[] buf;
protected int count;
private int bufLength;

public LogOutputStream() {
    bufLength = DEFAULT_BUFFER_LENGTH;
    buf = new byte[DEFAULT_BUFFER_LENGTH];
    count = 0;
}

public void close() {
    flush();
    hasBeenClosed = true;
}

public void write(final int b) throws IOException {
    if (hasBeenClosed) {
        throw new IOException("The stream has been closed.");
    }
    if (b == 0) {
        return;
    }
    if (count == bufLength) {
        final int newBufLength = bufLength + DEFAULT_BUFFER_LENGTH;
        final byte[] newBuf = new byte[newBufLength];

        System.arraycopy(buf, 0, newBuf, 0, bufLength);

        buf = newBuf;
        bufLength = newBufLength;
    }
    buf[count] = (byte) b;
    count++;
}

public void flush() {
    if (count == 0) {
        return;
    }
    if (count == LINE_SEPERATOR.length()) {
        if (((char) buf[0]) == LINE_SEPERATOR.charAt(0)
                && ((count == 1) ||
                ((count == 2) && ((char) buf[1]) == LINE_SEPERATOR.charAt(1)))) {
            reset();
            return;
        }
    }
    final byte[] theBytes = new byte[count];
    System.arraycopy(buf, 0, theBytes, 0, count);
    log(new String(theBytes));
    reset();
}


private void reset() {
    count = 0;
}

public abstract void log(String message);
}

然后只需创建它的一个子类,public void log(String message)用更新 UI 的代码来实现它,就完成了。

于 2012-09-14T15:54:33.300 回答