2013-06-12 50 views
0

我尝试使用进度条实现SFTP上传。带进度监视器的JSch上传

遗憾的是没有更新进度条...

这里是我的代码的一部分:

public class MainView extends JFrame implements SftpProgressMonitor { 

    private static final Logger LOG = Logger.getLogger(MainView.class); 
    private String _source; 
    private JProgressBar _progressBar; 
    private JButton _button; 

    public MainView() { 
     initComponents(); 
    } 

    void initComponents() { 
     _button = new JButton("Send"); 
     _button.addActionListener(new ActionListener() { 
      // If clicked, send event to controller... 
     }); 
     _progressBar = new JProgressBar(); 
     // Do init stuff here 
     // ... 
    } 

    @Override 
    public boolean count(long byteTransfered) { 
     int transfered = _progressBar.getValue(); 
     transfered += byteTransfered; 
     _progressBar.setValue(transfered); 
     return true; 
    } 

    @Override 
    public void end() { 
     LOG.info("Transfer of "+_source+" finished!"); 
    } 

    @Override 
    public void init(int op, String src, String dest, long max) { 
     _progressBar.setValue(0); 
     _progressBar.setMinimum(0); 
     _progressBar.setMaximum((int) max); 
     _source = src; 
    } 
} 


public class Controller { 

    private final MainView _view; 
    private final SftpClient _ftp; 
    private final Server _server; 

    public Controller() { 
     _server = new Server("192.168.0.1"); 
     _view = new MainView(); 
     _ftp = new SftpClient(_server); 

     _view.setVisible(true); 
    } 

    public void send() { 
     Executor executor = Executors.newSingleThreadExecutor(); 
     executor.execute(new Runnable() { 
      public void run() { 
       File testFile = new File("/PathToFile/file.txt"); 
       String remoteDir = "/MyRemoteDir/"; 
       _ftp.put(testFile, remoteDir, testFile.getName(), _view); 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     Controller controller = new Controller(); 
    } 
} 

public class SftpClient { 
    private static final Logger LOG = Logger.getLogger(SftpClient.class); 

    /** Connection port number */ 
    public static final int PORT = 22; 

    /** SECURED protocol name */ 
    public static final String PROTOCOL = "sftp"; 

    /** Connection time out in milliseconds */ 
    public static final int TIME_OUT = 3000; 

    private Server _server; 
    /** This class serves as a central configuration point, and as a factory for Session objects configured with these settings */ 
    private JSch _client; 
    /** A session represents a connection to a SSH server */ 
    private Session _session; 
    /** Channel connected to a SECURED server (as a subsystem of the SSH server) */ 
    private ChannelSftp _channelSftp; 

    /** 
    * Value returned by the last executed command. 
    */ 
    private int _exitValue; 

    public SftpClient(Server server) { 
     _client = new JSch(); 
     _server = server; 
    } 

    protected void connect() throws AuthenticationException, Exception { 
     try { 
      if (_client == null) { 
       _client = new JSch(); 
      } 
      if (_session == null) { 
       _session = _client.getSession(_server.getLogin(), _server.getAddress(), PORT); 
       _session.setConfig("StrictHostKeyChecking", "no"); 
       _session.setPassword(_server.getPassword()); 
       if (LOG.isDebugEnabled()) { 
        LOG.debug("Connecting to "+_server.getAddress()+" with login "+_server.getLogin()+"..."); 
       } 
      } 
      if (!_session.isConnected()) { 
       _session.connect(TIME_OUT); 
      } 

      if(_channelSftp == null || _channelSftp.isConnected() == false) { 
       Channel c = _session.openChannel(PROTOCOL); 
       c.connect(); 
       // disconnect previous channel if it has not been killed properly 
       if (_channelSftp != null && _channelSftp.isConnected()) { 
        _channelSftp.disconnect(); 
       } 
       _channelSftp = (ChannelSftp) c;    
      } 

      if (LOG.isInfoEnabled()) { 
       LOG.info("Connected to "+_server.getAddress()+" with login "+_server.getLogin()); 
      } 
     } catch(JSchException e) { 
      if ("Auth fail".equals(e.getMessage())) { 
       throw new AuthenticationException(e); 
      } else { 
       throw new Exception(e); 
      } 
     } 
    } 

    protected void connect(String path) throws AuthenticationException, Exception { 
     connect(); 
     if (_channelSftp != null && _channelSftp.isConnected()) { 
      _channelSftp.cd(path); 
     } 
    } 

    @Override 
    public void disconnect() { 
     if (_channelSftp != null && _channelSftp.isConnected()) { 
      _channelSftp.disconnect(); 
      _channelSftp.exit(); 
     } 
     if (_session != null && _session.isConnected()) { 
      _session.disconnect(); 
      if (LOG.isInfoEnabled()) { 
       LOG.info("SECURED FTP disconnected"); 
      } 
     } 
    } 

    @Override 
    public void put(File localFile, String destPath, SftpProgressMonitor monitor) throws Exception { 
     put(localFile, destPath, localFile.getName(), monitor); 
    } 

    @Override 
    public void put(File localFile, String destPath, String remoteFileName, SftpProgressMonitor monitor) throws Exception { 
     if (LOG.isInfoEnabled()) { 
      LOG.info("Send file "+localFile+" to "+_server+" in "+destPath); 
     } 
     if (localFile == null) { 
      _exitValue = -1; 
      LOG.error("The given local file is null. Aborting tranfer."); 
      return; 
     } 
     if (!localFile.exists()) { 
      _exitValue = -1; 
      LOG.error("'"+localFile+"' doesn't exist. Aborting tranfer."); 
      return; 
     } 
     if(!localFile.canRead()) { 
      _exitValue = -1; 
      LOG.error("Cannot read '"+localFile+"'. Aborting tranfer."); 
      return;   
     } 

     final InputStream input = new BufferedInputStream(new FileInputStream(localFile)); 
     if (input == null || input.available() <= 0) { 
      _exitValue = -1; 
      LOG.error("Cannot read file "+localFile); 
      return; 
     } 
     try { 
      connect(destPath); 
      _channelSftp.put(input, remoteFileName, monitor); 
      _exitValue = _channelSftp.getExitStatus(); 

     } catch(SftpException e){ 
      throw new IOException(e); 
     } finally { 
      if (_channelSftp != null && _channelSftp.isConnected()) { 
       _channelSftp.disconnect(); 
       _channelSftp.exit(); 
      } 
      IOUtils.closeQuietly(input); 
     } 
    } 
} 

count()方法不会被调用。 init的源和目标字符串都包含-。我做错了吗?

回答

0

我改变了我的代码,它现在可以工作。我不再使用put(InputStream src, String dst, int mode),而是使用put(String src, String dst, SftpProgressMonitor monitor)

我也实现了DefaultBoundedRangeModel类。它直接修改JProgressBar,对我来说更有趣,因为我有几个文件要传输。

public class ProgressModel extends DefaultBoundedRangeModel implements SftpProgressMonitor { 

    /** Logger */ 
    private static Logger LOG = Logger.getLogger(ProgressModel.class); 
    private String _fileBeingTransfered; 

    /** 
    * Constructs the model. 
    */ 
    public ProgressModel() { 
     _fileBeingTransfered = ""; 
    } 

    @Override 
    public boolean count(long count) { 
     int value = (int) (getValue() + count); 
     setValue(value); 
     fireStateChanged(); 
     if(value < getMaximum()) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public void end() { 
     LOG.info(_fileBeingTransfered+" transfert finished."); 
     if(getValue() == getMaximum()) { 
      LOG.info("All transfers are finished!"); 
     } 
    } 

    @Override 
    public void init(int op, String src, String dest, long max) { 
     LOG.info("Transfering "+src+" to "+dest+" | size: "+max); 
     _fileBeingTransfered = src; 
    } 
} 

我不知道是什么导致了我的问题。也许这是put方法。

-1

为了获得更新,您必须将对监视器的引用发送到FTP客户端。而你这样做:

_ftp.put(testFile, remoteDir, testFile.getName(), _view);

但是什么_view是什么?它是从未初始化的类Controllerprivate final字段。因此它是null。您将回拨方法count()实施到类MainView中,但不要将其引用到FTP客户端。我不知道你在哪里创建了Controller的实例,但是你应该将参考MainView的实例传递给它。

+0

对不起,我修剪了代码并删除了Controller的构造函数。如果它让你感到困惑,我会编辑代码。 – Maxbester

+0

我很高兴知道downvoter的原因。 OP询问问题,我试图帮助他。 – AlexR

+0

我更新了我的问题,但您没有更新您的答案。所以你的答案不再相关(并且实际上并不是......也许评论会更好)。此外,现在你已经回答了,没有人阅读这篇文章了... 我仍然卡住了。请更新您的答案,我会很乐意为此付出努力。 – Maxbester