2017-06-05 115 views
0

我正在開發一個程序在Java文件直接下載到我的服務器,對於我使用jSch通過ssh連接,並做了wget命令,但我想將輸出流式傳輸到JTextArea,而且我已經做到了,但是它只會在下載完成時打印出來,並且我希望將它作爲wget命令的輸出實時打印出來。的Java jSch Exec用進度條和實時輸出到一個JTextArea

CustomOutputStream代碼:

public class CustomOutputStream extends OutputStream{ 
private JTextArea textArea; 

    public CustomOutputStream(JTextArea textArea) { 
     this.textArea = textArea; 
    } 

    @Override 
    public void write(int b) throws IOException { 
     // redirects data to the text area 
     textArea.append(String.valueOf((char) b)); 
     // scrolls the text area to the end of data 
     textArea.setCaretPosition(textArea.getText().length()); 
    } 

    @Override 
    public void write(byte[] b, int off, int len) throws IOException { 
     String s = new String(b,off,len); 
     textArea.append(s); 
     textArea.setCaretPosition(textArea.getText().length()); 
    } 

    @Override 
    public void write(byte[] b) throws IOException { 
     this.write(b, 0, b.length); 
    } 

}

這裏是Exec的代碼:

Properties props = new Properties(); 
    props.put("StrictHostKeyChecking", "no"); 
    int port = 22; 

    JSch jsch=new JSch(); 

    Session session=jsch.getSession(username, host, 22); 
    session.setConfig(props); 
    session.setPassword(password); 
    session.connect(); 
    String command = "cd " + info.downPath + " && printf \"" + downLinks + "\" l> d.txt && wget -i d.txt"; 
    Channel channel=session.openChannel("exec"); 
    InputStream in=channel.getInputStream(); 
    OutputStream out = channel.getOutputStream(); 
    ((ChannelExec)channel).setCommand(command); 
    //((ChannelExec)channel).setErrStream(System.err); 
    //((ChannelExec)channel).setOutputStream(System.out); 
    ((ChannelExec)channel).setErrStream(new CustomOutputStream(taOutput)); 
    //((ChannelExec)channel).setOutputStream(new CustomOutputStream(taOutput)); 
    channel.connect(); 
    byte[] tmp=new byte[1024]; 
    while(true){ 
     while(in.available()>0){ 
     int i=in.read(tmp, 0, 1024); 
     if(i<0)break; 
     System.out.print(new String(tmp, 0, i)); 
     } 
     if(channel.isClosed()){ 
     if(in.available()>0) continue; 
     System.out.println("exit-status: "+channel.getExitStatus()); 
     break; 
     } 
     try{Thread.sleep(1000);}catch(Exception ee){} 
    } 
    channel.disconnect(); 
    session.disconnect(); 
    bar.setValue(100); 
+0

好的,那麼會發生什麼? CustomOutputStream是否被調用過? +你在什麼線程上執行代碼? –

+0

這就是所謂的,並打印出來,但只有當下載完成後...我想它流實時..圖是它所打印:http://i.imgur.com/u9NM8su.png –

+0

這裏是一個gif,它是如何發生的:https://gyazo.com/b583a48d8faf03358a57fb5dabfa4d11 –

回答

0

嘗試{了Thread.sleep(1000);}趕上(例外EE){}

您的代碼可能執行的Event Dispatch Thread (EDT)和Thread.sleep代碼(...)爲防止次從重新繪製自己直到任務完成執行。

所以解決的辦法就是啓動了長時間運行的任務,一個單獨的線程,因此EDT能夠對事件做出響應。

一個簡單的方法做,這是使用SwingWorker。請閱讀Concurrency in Swing上的Swing教程部分。本教程解釋了關於EDTSwingWorker的更多信息。

+0

謝謝= D,在我做了一些搜索之後,我建立了一個新的線程來完成這項任務,並且一切順利。 –

0

一些幫助E多的搜索後,我只需要創建一個新的線程處理程序的連接。

這裏是我採取了例如:從這個鏈接 :

one = new Thread() { 
public void run() { 
    try { 
     System.out.println("Does it work?"); 

     Thread.sleep(1000); 

     System.out.println("Nope, it doesnt...again."); 
    } catch(InterruptedException v) { 
     System.out.println(v); 
    } 
} 

};

one.start();