如何创建另一个"版本"过程()

时间:2015-04-06 21:16:29

标签: java multithreading swing swingworker

我正在使用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

1 个答案:

答案 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);
   }
}

这些都不是专业代码,只是我玩过的垃圾。