控制台输出捕获的可用解决方案 – java

我正在制作一个能够从内部运行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种方法,但是没有一种方法可以运行或者可以理解我可以运行它。 我需要代码足够简单,因为这将必须输出proccess将在默认系统的控制台(cmd,终端)中写入然后停止(我认为这可以是一个方法调用)。 我对这种东西很不好,即使multithreading解决方案可以满足我的需求,也没有太专业,我只是需要它才能工作。 您需要的任何信息,请求! 提前致谢! 🙂

如果您想阅读本文,我不知道您,但是您知道,在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); } 

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