有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带进度监视器的java JSch上载

我尝试用进度条实现SFTP上传

很遗憾,进度条没有更新

以下是我代码的一部分:

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的源字符串和目标字符串都包含-。我做错了吗


共 (2) 个答案

  1. # 1 楼答案

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

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

    然而_view是什么?它是类Controllerprivate final字段,从未初始化。因此它是null。您将回调方法count()实现到类MainView中,但没有将对它的引用发送到FTP客户端。我不知道在哪里创建Controller的实例,但应该将对MainView实例的引用传递给它

  2. # 2 楼答案

    我已经更改了代码,现在可以使用了。我不再使用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方法