繁体   English   中英

Java jSch Exec,带有进度条并实时输出到JTextArea

[英]Java jSch Exec with progress bar and real time output to a JTextArea

我正在用Java开发一个程序,将文件直接下载到我的服务器上,为此,我正在使用jSch通过ssh连接并执行wget命令,但是我想将输出流式传输到JTextArea,并且我已经做到了这一点,但它只会在下载完成后才打印,我想将其实时打印为wget命令的输出。

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);

试试{Thread.sleep(1000);}捕获(异常ee){}

您的代码可能正在Event Dispatch Thread (EDT)上执行,并且Thread.sleep(...)阻止GUI重新绘制自身,直到任务完成执行为止。

因此解决方案是为长期运行的任务启动一个单独的线程,以便EDT能够响应事件。

一个简单的方法是使用SwingWorker 阅读Swing教程中有关Swing中的并发性的部分。 本教程详细介绍了EDTSwingWorker

经过更多搜索后,我只是创建了一个新线程来处理连接。

这是我采取的示例:从此链接:

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM