在项目中准备替换ActiveMQ的http方式为sftp方式下载文件。由于sftp需要开通22端口,也就是说ssh也能用了,因此也可以通过ssh执行一些命令。
需要引用jsch-0.1.44.jar
首先直接上sftp的代码。
package com.icbc.SFTP;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class MediaSftp {
public Session session;
private String usr;
private String pwd;
public MediaSftp(String usr,String pwd,String ip) throws JSchException {
this.usr = usr;
this.pwd=pwd;
Connect(ip);
}
public void Connect(String ip) throws JSchException{
JSch jsch = new JSch();
try{
this.session = jsch.getSession(this.usr, ip,22);
if(session != null){
session.setPassword(this.pwd);
session.setConfig("StrictHostKeyChecking","no");
session.setTimeout(30000);
session.connect();
System.out.println("connect to "+ip);
if(session != null && !session.isConnected()){
this.close();
}
}
}catch(JSchException e){
throw e;
}
}
public void close(){
if(session != null && session.isConnected()){
session.disconnect();
// this.isConnectSSH = false;
}else{
}
}
public boolean download(String downloadFile,String saveFile) throws Exception{
try {
ChannelSftp sftp = (ChannelSftp)
session.openChannel("sftp");
sftp.connect();
sftp.cd("/opt/activemq/apache-activemq-5.13.4/webapps/fileserver/media/");
File file = new File(saveFile);
System.out.println(saveFile);
File parentFile = file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
InputStream in = null;
FileOutputStream outputStream = new FileOutputStream(file);
in = sftp.get(downloadFile);
//可通过byte数组长度控制下载速度
byte[] buffer = new byte[20480];
int count = 0;
while ((count = in.read(buffer)) != -1) {
if (count == 0) break;
outputStream.write(buffer, 0, count);
}
in.close();
outputStream.close();
outputStream.flush();
sftp.disconnect();
this.close();
return true;
} catch (Exception e) {
throw e;
}
}
}
调用时先实例化这个类,然后直接调用download方法就可以了。入参是要下载的文件名,和本地要保存的路径,然后拼成本地文件名传入download方法。返回值是下载耗时。
public long getMedia(String hostip,String fileName, String localPath) throws Exception {
MediaSftp sftp = new MediaSftp("username","passwords",hostip);
String localFile = localPath+fileName;
long start = System.currentTimeMillis();
sftp.download(fileName, localFile);
return System.currentTimeMillis()-start;
}
此外,jsch还提供了远程ssh协议登陆后执行命令的方法。下面是一个执行命令获取目录中最近更新的文件名的方法,可以把这个方法添加到MediaSftp类里,实例化MedisSftp类建立连接后,就可以调用这个方法了。
public String getLatestFileName(String patterns) throws Exception {
//执行的命令,这里为查找目录下最近更新的文件名带有patterns的文件
String cmd = "ls -ltr /opt/activemq/apache-activemq-5.13.4/webapps/fileserver/media/|grep "+patterns+"|tail -1|awk {'print $NF'}\n";
ByteArrayOutputStream retOut = new ByteArrayOutputStream();
ChannelShell channelShell = (ChannelShell)session.openChannel("shell");
PipedInputStream cmdIn = new PipedInputStream();
PipedOutputStream cmdOut = new PipedOutputStream(cmdIn);
channelShell.setInputStream(cmdIn);
channelShell.setOutputStream(retOut);
channelShell.connect(30000);
cmdOut.write(cmd.getBytes());
cmdOut.flush();
//缓冲时间和执行时间
Thread.sleep(2000);
cmdOut.close();
cmdIn.close();
String retMsg = retOut.toString();
retOut.close();
channelShell.disconnect();
//得到的结果包含很多行,需要处理
String[] retArr= retMsg.split("\n");
return retArr[retArr.length-2].trim();
}
网友评论