Java实现sftp及远程执行命令

在项目中准备替换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();
}

你可能感兴趣的:(Java实现sftp及远程执行命令)