1

我尝试使用进度条实现 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 的源字符串和目标字符串都包含-. 我做错了吗?

4

2 回答 2

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 方法。

于 2013-06-18T11:16:05.720 回答
-1

为了获得更新,您必须向 FTP 客户端发送监控参考。你这样做:

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

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

于 2013-06-12T07:56:28.600 回答