[英]Java System.out not Being Redirected
I have a simple task of capturing all System.out
output; 我有一个捕获所有
System.out
输出的简单任务; I am however failing: 然而,我失败了:
public class Main {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
ArrayList<String> history = new ArrayList<>();
StringBuilder output = new StringBuilder();
StringBuilder input = new StringBuilder();
JPanel panel = new JPanel();
JTextArea txt = new JTextArea();
String PROMPT = "> ";
Runnable show = new Runnable() {
public void run() {
txt.setText("");
for (String line: history) txt.append(line + "\n");
txt.append(PROMPT);
txt.append(output.toString());
txt.setCaretPosition(txt.getText().length());
}
};
PrintStream os = new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
if (b == 13) {
history.add(input.toString());
input = new StringBuilder();
SwingUtilities.invokeLater(show);
} else input.append((char)b);
}
});
void init(String title) {
panel.setLayout(new BorderLayout());
txt.setLineWrap(true);
txt.setFont(new Font("Courier", Font.PLAIN, 16));
txt.setBackground(Color.BLACK);
txt.setForeground(Color.GREEN);
txt.setCaretColor(Color.GREEN);
txt.setEditable(false);
txt.setText(PROMPT);
txt.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\n') {
System.setOut(os);
System.setErr(os);
String result = output.toString();
history.add(PROMPT + result);
try {
engine.eval(result);
} catch (ScriptException ex) {
history.add(ex.toString());
}
output = new StringBuilder();
} else {
output.append(e.getKeyChar());
}
SwingUtilities.invokeLater(show);
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
});
panel.add(txt, BorderLayout.CENTER);
JFrame frame = new JFrame(title);
frame.setSize(650, 425);
frame.setContentPane(panel);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String args[]) {
new Main().init("javascript");
}
}
I should note the output I am looking for comes from something like: 我应该注意我正在寻找的输出来自:
new ScriptEngineManager().getEngineByName("js").eval("print(\"test\");");
The output is not going anywhere other than normal STDOUT
aka System.out
. 除了普通的
STDOUT
又称System.out
之外,输出不会发送到任何地方。 Why? 为什么?
ScriptEngine output redirection: ScriptEngine输出重定向:
To redirect the output of a script you first have to get its ScriptContext instance, that has a method called setWriter(Writer). 要重定向脚本的输出,首先必须获取其ScriptContext实例,该实例具有名为setWriter(Writer)的方法。 That sets the output of the ScriptEngine.
这设置了ScriptEngine的输出。
For that you first need a Writer. 为此你首先需要一个作家。 This can be simple like this one:
这可以像这样简单:
public class CaptureWriter extends Writer
{
private StringBuilder m_build;
public CaptureWriter(StringBuilder build)
{
m_build = build;
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException
{
m_build.insert(m_build.length(), cbuf, off, len);
}
@Override
public void flush() throws IOException
{
}
@Override
public void close() throws IOException
{
}
}
This writes all input into a StringBuilder. 这会将所有输入写入StringBuilder。
Then you register it into a ScriptContext 然后将其注册到ScriptContext中
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.getContext().setWriter(new CaptureWriter(m_mess));
When running this simple program: 运行这个简单的程序时:
StringBuilder build = new StringBuilder();
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.getContext().setWriter(new CaptureWriter(build));
try
{
engine.eval("print(\"Hello\")");
engine.eval("print(\"World\")");
engine.eval("print(\"You\")");
engine.eval("print(\"There\")");
} catch(ScriptException e)
{
e.printStackTrace();
}
System.out.println(build);
The output is the buffered output of the script: 输出是脚本的缓冲输出:
Hello
World
You
There
You can of course hook anything into the write method of the Writer implementation, this is just an example. 您当然可以将任何内容挂钩到Writer实现的write方法中,这只是一个示例。
System.out redirection: System.out重定向:
To capture the System.out output you have to make your own PrintStream implementation, it can be very simple like: 要捕获System.out输出,您必须创建自己的PrintStream实现,它可以非常简单,如:
public class Capture extends PrintStream
{
private StringBuilder m_build;
public Capture(OutputStream out, StringBuilder build)
{
super(out);
m_build = build;
}
public void println(String s)
{
super.println(s);
m_build.append(s + "\n");
}
}
Then you need to register it in the runtime: 然后你需要在运行时注册它:
StringBuilder build = new StringBuilder();
System.setOut(new Capture(System.out, build));
Then every time System.out.println is called it works like the overriding PrintStream should and the message gets written into the provided StringBuilder. 然后每次调用System.out.println时,它都会像重写PrintStream那样工作,并且消息会写入提供的StringBuilder。
To capture other messages you'll need to override other methods. 要捕获其他消息,您需要覆盖其他方法。
You can capture System.out be providing a PrintStream that you control ... try something like this 您可以捕获System.out提供您控制的PrintStream ...尝试这样的事情
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
PrintStream old = System.out;
System.setOut(ps);
System.out.println("This will be captured :P");
System.out.flush();
System.setOut(old);
System.out.println("He is what was captured : " + baos.toString());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.