我尝试使用进度条实现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的源和目标字符串包含-
。我做错了吗?
答案 0 :(得分: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 :(得分:-1)
为了获得更新,您必须将监视器的引用发送到FTP客户端。你这样做:
_ftp.put(testFile, remoteDir, testFile.getName(), _view);
然而_view
是什么?它是类private final
的{{1}}字段,从未初始化。因此它是Controller
。您已将回调方法null
实现到类count()
中,但不将其引用发送到FTP客户端。我不知道你在哪里创建MainView
的实例,但你应该将Controller
的实例的引用传递给它。