我正在使用MessageConsole.java将标准输出流重定向到文本窗格。完成后,我认为重定向错误流也会很好。为此,我将另一个缓冲读卡器添加到this答案的修改版本中。接下来是我的问题所在 - 我需要process()
方法的另一个“版本”打印到System.err
而不是System.out
。我试过谷歌搜索它,但我的结果是愚蠢的。我如何添加需要特定参数的另一个版本的Overridden方法?代码可能看起来像第二个例子。
我当前的代码
class ConsoleThread extends SwingWorker<Void, String> {
String command;
ConsoleThread(String cmd) {
command = cmd;
}
@Override
protected Void doInBackground() throws Exception {
Process ps = Runtime.getRuntime().exec(command);
BufferedReader is = new BufferedReader(new InputStreamReader(ps.getInputStream()));
BufferedReader es = new BufferedReader(new InputStreamReader(ps.getErrorStream()));
String outputLine;
String errorLine;
while ((outputLine = is.readLine()) != null) {
publish(outputLine);
}
while ((errorLine = es.readLine()) != null) {
publish(errorLine);
}
is.close();
return null;
}
@Override
protected void process(List<String> chunk) {
for (String string : chunk) {
System.out.println(string);
}
}
}
答案可能是什么样的(一段代码值得千言万语)
class ConsoleThread extends SwingWorker<Void, String> {
String command;
ConsoleThread(String cmd) {
command = cmd;
}
@Override
protected Void doInBackground() throws Exception {
Process ps = Runtime.getRuntime().exec(command);
BufferedReader is = new BufferedReader(new InputStreamReader(ps.getInputStream()));
BufferedReader es = new BufferedReader(new InputStreamReader(ps.getErrorStream()));
String outputLine;
String errorLine;
while ((outputLine = is.readLine()) != null) {
publish(outputLine);
}
while ((errorLine = es.readLine()) != null) {
publish2(errorLine);
}
is.close();
return null;
}
@Override
protected void process(List<String> chunk) {
for (String string : chunk) {
System.out.println(string);
}
}
@Override
protected void process2(List<String> chunk) {
for (String string : chunk) {
System.err.println(string);
}
}
}
将process2()
视为原始process()
。
要清楚,当前代码有效,但会将任何错误消息发送到输出流而不是错误流。 (见this)
答案 0 :(得分:1)
您不需要&#34;另一个版本的Process&#34;一点都不您只需要两个新线程,每个Stream一个,包括InputStream和ErrorStream。创建两个Runnables,将while循环放在那些Runnables中,将Streams传递给它们,然后在自己的线程中运行Runnables。
您可以将要发布的消息包装在标识方法的流源的包装器对象中,允许您使用相同的发布/进程对,或者可以使用其他通知方法,如PropertyChangeListeners和PropertyChangeSupport。
为了它的价值,我在以前尝试读取错误和输出流时使用了这段代码:
enum GobblerType.java
public enum GobblerType {
ERROR, OUTPUT
}
类StreamGobbler.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
public class StreamGobbler implements Runnable {
private InputStream is;
private GobblerType type;
private OutputStream os;
public StreamGobbler(InputStream is, GobblerType type) {
this(is, type, null);
}
public GobblerType getType() {
return type;
}
public StreamGobbler(InputStream is, GobblerType type, OutputStream redirect) {
this.is = is;
this.type = type;
this.os = redirect;
}
public void run() {
try {
PrintWriter pw = null;
if (os != null) {
pw = new PrintWriter(os, true);
}
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
if (pw != null) {
pw.println(line);
}
// System.out.println(type + "> " + line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
class TextAreaOutputStream.java - 我对这个问题最为怀疑
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class TextAreaOutputStream extends OutputStream {
private final JTextArea textArea;
private final StringBuilder sb = new StringBuilder();
private String title;
public TextAreaOutputStream(final JTextArea textArea, String title) {
this.textArea = textArea;
this.title = title;
sb.append(title + "> ");
}
@Override
public void flush() {
}
@Override
public void close() {
}
@Override
public void write(int b) throws IOException {
if (b == '\r')
return;
if (b == '\n') {
final String text = sb.toString() + "\n";
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text);
}
});
sb.setLength(0);
sb.append(title + "> ");
return;
}
sb.append((char) b);
}
}
这些都不是专业代码,只是我玩过的垃圾。