使用Process动态运行java代码
我创建了一个类,它动态编译,加载CustomClassLoader,并通过调用它的main
方法执行内存中的 java源(即:没有类文件)java源代码。
我需要捕获StdOut
, StdIn
和StdErr
,尽管在我当前的代码中不可能这样做。 ( Compiler API + Classloader + Reflection
)
我的要求可能与此问题中的要求相同 – 并且如接受的答案所示 – 使用java.lang.Process 。 如果我在文件系统中有物理文件,这会更容易,但在这种情况下我没有。
我打算删除Classloader + Reflection
策略并改用建议; 虽然,我不熟悉实际使用Process类重定向Std*
。
我怎么能在Java 7中做到这一点? (片段非常受欢迎)或者更重要的是,有更好的方法吗?
- 备份现有的输出流。
PrintStream realSystemOut = System.out;
-
将其设置为其他outputstream [fileOutputStream或其他一些流] PrintStream overridePrintStream = new PrintStream(new FileOutputStream(“log.txt”));
System.setOut(overridePrintStream);
—–过程—–
-
将实际流放回System.out
System.setOut(realSystemOut);
谢谢
Java允许您提供自己的PrintStream
来覆盖stdout
和stderr
以及stdin
的InputStream
。
就个人而言,我不喜欢简单地丢弃原始流,因为我倾向于只想重定向或解析它,而不是阻止它(尽管你也可以这样做)。
这是一个简单的想法示例……
import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; public class RedirectStdOut { public static void main(String[] args) { Consumer stdConsumer = new Consumer() { @Override public void processLine(StreamCapturer capturer, String text) { } @Override public void processCharacter(StreamCapturer capturer, char character) { capturer.getParent().print(character); } }; StreamCapturer stdout = new StreamCapturer(stdConsumer, System.out); StreamCapturer stderr = new StreamCapturer(stdConsumer, System.err); System.setOut(new PrintStream(stdout)); System.setErr(new PrintStream(stderr)); System.out.println("This is a test"); System.err.println("This is an err"); } public static interface Consumer { public void processLine(StreamCapturer capturer, String text); public void processCharacter(StreamCapturer capturer, char character); } public static class StreamCapturer extends OutputStream { private StringBuilder buffer; private Consumer consumer; private PrintStream parent; private boolean echo = false; public StreamCapturer(Consumer consumer, PrintStream parent) { buffer = new StringBuilder(128); this.parent = parent; this.consumer = consumer; } public PrintStream getParent() { return parent; } public boolean shouldEcho() { return echo; } public void setEcho(boolean echo) { this.echo = echo; } @Override public void write(int b) throws IOException { char c = (char) b; String value = Character.toString(c); buffer.append(value); if (value.equals("\n")) { consumer.processLine(this, value); buffer.delete(0, buffer.length()); } consumer.processCharacter(this, c); if (shouldEcho()) { parent.print(c); } } } }
现在StreamCapturer
能够在你想要的时候回显输出,我已经关闭它来演示使用Consumer
。 我通常会使用Consumer
来处理流中的内容,根据您的需要,您可以等待整行或处理各个字符……