簡體   English   中英

帶有進度監視器的 JSch 上傳

[英]JSch upload with progress monitor

我嘗試使用進度條實現 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 的源字符串和目標字符串都包含- 我做錯了嗎?

我已經更改了我的代碼,現在可以使用了。 我不再使用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 方法。

為了獲得更新,您必須向 FTP 客戶端發送對監視器的引用。 你這樣做:

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

然而_view是什么? 它是Controller類的private final字段,從未被初始化。 因此它是null 您將回調方法count()到類MainView但未將對其的引用發送到 FTP 客戶端。 我不知道您在哪里創建Controller實例,但您應該將MainView實例的引用傳遞給它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM