2015-04-06 45 views
0

我正在使用MessageConsole.java將標準輸出流重定向到文本窗格。完成之後,我認爲重定向錯誤流也不錯。爲此,我添加了另一個緩衝閱讀器到this的修改版本答案。接下來是我的問題所在 - 我需要process()方法的另一個「版本」,該方法打印到System.err而不是System.out。我嘗試了谷歌搜索,但我的結果是沒有。我將如何添加另一個需要特定參數的重寫方法的版本?代碼可能看起來像第二個例子。如何創建另一個「版本」的過程()

我當前的代碼

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

它可能不會回答這個問題,但是:我建議您考慮爲此創建一個專用的基礎結構,而不是*依賴於消息控制檯類。鏈接的答案已經顯示瞭如何寫入文本區域,您可以稍微修改一下。 – Marco13

回答

1

根本不需要「另一個版本的Process」。您只需要兩個新線程,一個用於每個Stream,一個用於InputStream和ErrorStream。創建兩個Runnables,將While循環放入這些Runnables中,將Streams傳遞給它們,然後在它們自己的線程中運行Runnables。

您可以將您希望發佈的消息封裝在包裝器對象中,該包裝器對象標識了方法的流源,允許您使用相同的發佈/過程對,或者可以使用其他通知方法,例如PropertyChangeListeners和PropertyChangeSupport 。


對於它的價值,我用這個代碼在以前的嘗試讀取錯誤和輸出流:

枚舉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); 
    } 
} 

這不是專業代碼,只是我玩過的垃圾。

+0

我曾想過這件事,但我想看看是否有另一種方式。 – CaffeineToCode

+0

@CaffeineToCode:「另一種方式」?你是什​​麼意思,你爲什麼要這麼做?您可以將您希望發佈的消息封裝在包裝器對象中,以標識方法的來源,從而允許您使用相同的發佈/過程對,或者可以使用其他通知方法,例如PropertyChangeListeners和PropertyChangeSupport。 –

+0

因爲我喜歡探索一切可能的做法。這是我學習的方式之一。 – CaffeineToCode

相關問題