在java开发中,遇到需要将linux系统中指定目录下的文件下载到windows本地的需求,下面聊聊通过sftp协议实现上传和下载。
1、sftp协议
jsch是java secure channel的缩写。jsch是一个ssh2的纯java实现。它允许你连接到一个ssh服务器,并且可以使用端口转发,x11转发,文件传输等,当然你也可以集成它的功能到你自己的应用程序。
sftp是secure file transfer protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的加密方法。sftp 为 ssh的一部份,是一种传输文件到服务器的安全方式。sftp是使用加密传输认证信息和传输的数据,所以,使用sftp是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的ftp要低得多,如果您对网络安全性要求更高时,可以使用sftp代替ftp。
2、sftp核心类
channelsftp类是jsch实现sftp核心类,它包含了所有sftp的方法,如:
- put(): 文件上传
- get(): 文件下载
- cd(): 进入指定目录
- ls(): 得到指定目录下的文件列表
- rename(): 重命名指定文件或目录
- rm(): 删除指定文件
- mkdir(): 创建目录
- rmdir(): 删除目录
其他参加源码。
jsch支持三种文件传输模式: - overwrite 完全覆盖模式,这是jsch的默认文件传输模式,即如果目标文件已经存在,传输的文件将完全覆盖目标文件,产生新的文件。
- resume 恢复模式,如果文件已经传输一部分,这时由于网络或其他任何原因导致文件传输中断,如果下一次传输相同的文件,则会从上一次中断的地方续传。
- append 追加模式,如果目标文件已存在,传输的文件将在目标文件后追加。
编写一个工具类,根据ip,用户名及密码得到一个sftp channel对象,即channelsftp的实例对象,在应用程序中就可以使用该对象来调用sftp的各种操作方法:
public class sftpchannel { session session = null; channel channel = null; private static final logger log = logger.getlogger(sftpchannel.class.getname()); public channelsftp getchannel(map<string, string> sftpdetails, int timeout) throws jschexception { string ftphost = sftpdetails.get(“host”); string port = sftpdetails.get("port"); string ftpusername = sftpdetails.get("username"); string ftppassword = sftpdetails.get("password"); int ftpport = 22; if (port != null && !port.equals("")) { ftpport = integer.valueof(port); } jsch jsch = new jsch(); // 创建jsch对象 session = jsch.getsession(ftpusername, ftphost, ftpport); // 根据用户名,主机ip,端口获取一个session对象 log.debug("session created."); if (ftppassword != null) { session.setpassword(ftppassword); // 设置密码 } properties config = new properties(); config.put("stricthostkeychecking", "no"); session.setconfig(config); // 为session对象设置properties session.settimeout(timeout); // 设置timeout时间 session.connect(); // 通过session建立链接 log.debug("session connected."); log.debug("opening channel."); channel = session.openchannel("sftp"); // 打开sftp通道 channel.connect(); // 建立sftp通道的连接 log.debug("connected successfully to ftphost = " + ftphost + ",as ftpusername = " + ftpusername + ", returning: " + channel); return (channelsftp) channel; } public void closechannel() throws exception { if (channel != null) { channel.disconnect(); } if (session != null) { session.disconnect(); } } }
3、实例
import com.jcraft.jsch.*; import java.io.bufferedinputstream; import java.io.bufferedoutputstream; import java.io.fileoutputstream; import java.io.inputstream; public class sftpdownloadwithratelimit { public static void main(string[] args) { string host = "hostname"; string username = "username"; string password = "password"; string remotefile = "/path/to/remote/file"; string localfile = "localfile"; int ratelimit = 1024; // 1kb/s jsch jsch = new jsch(); try { session session = jsch.getsession(username, host, 22); session.setconfig("stricthostkeychecking", "no"); session.setpassword(password); session.connect(); channelsftp channelsftp = (channelsftp) session.openchannel("sftp"); channelsftp.connect(); // 设置下载速率限制 channelsftp.setinputstream(new bufferedinputstream(channelsftp.get(remotefile), ratelimit)); inputstream inputstream = channelsftp.get(remotefile); bufferedoutputstream outputstream = new bufferedoutputstream(new fileoutputstream(localfile)); byte[] buffer = new byte[1024]; int bytesread; while ((bytesread = inputstream.read(buffer)) != -1) { outputstream.write(buffer, 0, bytesread); } inputstream.close(); outputstream.close(); channelsftp.disconnect(); session.disconnect(); } catch (jschexception | sftpexception | java.io.ioexception e) { e.printstacktrace(); } } }
或
import com.jcraft.jsch.channelsftp; import com.jcraft.jsch.jsch; import com.jcraft.jsch.session; import java.io.fileoutputstream; import java.io.inputstream; public class sftpdownloadwithratelimit { public static void main(string[] args) { string host = "sftp.example.com"; string username = "username"; string password = "password"; int port = 22; string remotefilepath = "/path/to/remote/file"; string localfilepath = "/path/to/local/file"; int downloadrate = 1024; // 1 kb/s try { jsch jsch = new jsch(); session session = jsch.getsession(username, host, port); session.setpassword(password); session.setconfig("stricthostkeychecking", "no"); session.connect(); channelsftp channelsftp = (channelsftp) session.openchannel("sftp"); channelsftp.connect(); inputstream inputstream = channelsftp.get(remotefilepath); fileoutputstream outputstream = new fileoutputstream(localfilepath); byte[] buffer = new byte[1024]; int bytesread; long starttime = system.currenttimemillis(); while ((bytesread = inputstream.read(buffer)) != -1) { outputstream.write(buffer, 0, bytesread); long elapsedtime = system.currenttimemillis() - starttime; long expectedtime = (outputstream.getchannel().size() / downloadrate) * 1000; if (elapsedtime < expectedtime) { thread.sleep(expectedtime - elapsedtime); } } inputstream.close(); outputstream.close(); channelsftp.disconnect(); session.disconnect(); system.out.println("file downloaded successfully."); } catch (exception e) { e.printstacktrace(); } } }
上面是根据指定速率进行下载。
4、工具类
import com.jcraft.jsch.*; import java.io.*; public class sftputil { private string host; private int port; private string username; private string password; public sftputil(string host, int port, string username, string password) { this.host = host; this.port = port; this.username = username; this.password = password; } public void uploadfile(string localfilepath, string remotefilepath) { try { jsch jsch = new jsch(); session session = jsch.getsession(username, host, port); session.setconfig("stricthostkeychecking", "no"); session.setpassword(password); session.connect(); channelsftp channelsftp = (channelsftp) session.openchannel("sftp"); channelsftp.connect(); channelsftp.put(new fileinputstream(localfilepath), remotefilepath); channelsftp.disconnect(); session.disconnect(); } catch (jschexception | sftpexception | filenotfoundexception e) { e.printstacktrace(); } } public void downloadfile(string remotefilepath, string localfilepath) { try { jsch jsch = new jsch(); session session = jsch.getsession(username, host, port); session.setconfig("stricthostkeychecking", "no"); session.setpassword(password); session.connect(); channelsftp channelsftp = (channelsftp) session.openchannel("sftp"); channelsftp.connect(); channelsftp.get(remotefilepath, new fileoutputstream(localfilepath)); channelsftp.disconnect(); session.disconnect(); } catch (jschexception | sftpexception | filenotfoundexception e) { e.printstacktrace(); } } }
jsch支持在文件传输时对传输进度的监控。可以实现jsch提供的sftpprogressmonitor接口来完成这个功能。
- init(): 当文件开始传输时,调用init方法。
- count(): 当每次传输了一个数据块后,调用count方法,count方法的参数为这一次传输的数据块大小。
- end(): 当传输结束时,调用end方法。
public class myprogressmonitor implements sftpprogressmonitor { private long transfered; @override public boolean count(long count) { transfered = transfered + count; system.out.println("currently transferred total size: " + transfered + " bytes"); return true; } @override public void end() { system.out.println("transferring done."); } @override public void init(int op, string src, string dest, long max) { system.out.println("transferring begin."); } }
到此这篇关于java中通过sftp协议实现上传下载的示例代码的文章就介绍到这了,更多相关java sftp上传下载内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论