欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java工具jsch.jar实现上传下载

程序员文章站 2024-03-02 15:42:22
在做运维的时候,我们一般使用shell脚本实现文件的服务器之间定时传输,那么对于一些不会shell脚本的童鞋,就得使用万能的编程语言了,这里我们介绍一款java操作ftp的...

在做运维的时候,我们一般使用shell脚本实现文件的服务器之间定时传输,那么对于一些不会shell脚本的童鞋,就得使用万能的编程语言了,这里我们介绍一款java操作ftp的工具,那就是jsch.jar。工具已经写好,可以根据实际情况做调整,注释很清晰。大家按需阅读:

package com.wdy.tools.utils.sftputil;
 
import java.io.file;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.inputstream;
import java.io.outputstream;
import java.util.arrays;
import java.util.collections;
import java.util.properties;
import java.util.vector;
 
import org.apache.commons.logging.log;
import org.apache.commons.logging.logfactory;
 
import com.jcraft.jsch.channel;
import com.jcraft.jsch.channelsftp;
import com.jcraft.jsch.jsch;
import com.jcraft.jsch.session;
 
/**
 * 利用jsch.jar针对sftp的上传和下载
 * 需要jar包:
 * commons-lang3-3.2.1.jar
 * commons-logging.jar
 * jsch-0.1.53.jar
 * log4j-1.2.17.jar
 * @author wangdy
 *
 */
public class jschsftputils {
 
 private static final log log = logfactory.getlog(jschsftputils.class);
 
 /**
 * 利用jsch包实现sftp下载文件
 * (这里是将serverpath下的指定扩展名的文件,全部下载到localpath下)
 * @param ip 主机ip
 * @param user 主机登陆用户名
 * @param psw 主机登陆密码
 * @param port 主机ssh2登陆端口,如果取默认值,传<=0的值,如-1
 * @param localpath 下载的本地目录的路径
 * @param serverpath 服务器目录
 * @param fileexetension 文件扩展名,格式如:'.txt'
 * @param isdelete 是否删除该路径下扩展名为fileexetension的远程文件
 * @throws exception
 */
 public static void sshsftpdownload(string ip, string user, string psw, int port, string serverpath, string localpath, string fileextension, boolean isdelete) throws exception {
 session session = null;
 channel channel = null;
 jsch jsch = new jsch();
 if (port <= 0) {
 // 连接服务器,采用默认端口
 session = jsch.getsession(user, ip);
 } else {
 // 采用指定的端口连接服务器
 session = jsch.getsession(user, ip, port);
 }
 // 如果服务器连接不上,则抛出异常
 if (session == null) {
 throw new exception("session is null");
 }
 // 设置登陆主机的密码
 session.setpassword(psw);// 设置密码
 // 设置第一次登陆的时候提示,可选值:(ask | yes | no)
// session.setconfig("stricthostkeychecking", "no");
 properties sshconfig = new properties();
 sshconfig.put("stricthostkeychecking", "no");
 session.setconfig(sshconfig);
 // 设置登陆超时时间ms
// session.connect(640);
 session.connect();
 log.info("session connected.");
 log.info("opening channel.");
 try {
 // 创建sftp通信通道
 channel = (channel) session.openchannel("sftp");
 channel.connect();
// channel.connect(1000);
 channelsftp sftp = (channelsftp) channel;
 log.info("connected to " + ip + ".");
 // 进入服务器指定的文件夹
 sftp.cd(serverpath);
 /**
 * 列出服务器指定的文件列表(可以加参数,指明要下载的文件类型)
 * 说明:如果fileextension不为空,则下载指定扩展名的文件集;
 * 如果fileextension为"",则下载该目录下所有类型的文件,如果是文件夹的话,会报错,如果您路径下有以.连接的文件夹,请注意,这是不可以的,程序会在过滤到该文件夹时中断
 */
 vector<?> v = null;
 if (fileextension != null && !"".equals(fileextension)) {
 v = sftp.ls("*"+fileextension);
 }else {
 try {
  v = sftp.ls("*.*");//ls -al | grep \"^-\"只显示文件---// ls -al | grep "^d"只显示目录包括.和..
 } catch (exception e) {
  log.info("您操作的是一个文件夹!");
 }
 }
 
 for (int i = 0; i < v.size(); i++) {
// log.info("fileinfos: "+v.get(i));
 string[] fileinfos = v.get(i).tostring().replaceall("\t", " ").split(" ");
 string filename = fileinfos[fileinfos.length-1];
 log.info("filename is: "+filename);
 // 以下代码实现从服务器下载一个文件到 本地
 inputstream instream = sftp.get(filename);
 outputstream outstream = new fileoutputstream(new file(localpath+"/"+filename));
 byte b[] = new byte[1024];
 int n;
 while ((n = instream.read(b)) != -1) {
  outstream.write(b, 0, n);
 }
 outstream.flush();
 outstream.close();
 instream.close();
 log.info("文件["+filename+"]下载成功!---->>>>下载到目录["+localpath+"]中.");
 //下载成功后,删除文件
 if (isdelete) {
  deleteonefile(serverpath, filename, sftp);
  log.info("文件["+filename+"]删除成功!");
 }
 }
 } catch (exception e) {
 e.printstacktrace();
 } finally {
 session.disconnect();
 channel.disconnect();
 }
 }
 
 /**
  * 利用jsch包实现sftp上传文件
  * @param ip 主机ip
  * @param user 主机登陆用户名
  * @param psw 主机登陆密码
  * @param port 主机ssh2登陆端口,如果取默认值,传<=0的值,如-1
  * @param localpath 本地目录
  * @param serverpath 服务器目录
  * @param fileextension 上传文件的扩展名 格式如:'.txt'
  */
 public static void sshsftpupload(string ip, string user, string psw, int port,string localpath, string serverpath, string fileextension) throws exception {
 session session = null;
 channel channel = null;
 jsch jsch = new jsch();
 if (port <= 0) {
 // 连接服务器,采用默认端口
 session = jsch.getsession(user, ip);
 } else {
 // 采用指定的端口连接服务器
 session = jsch.getsession(user, ip, port);
 }
 // 如果服务器连接不上,则抛出异常
 if (session == null) {
 log.info("session is null,服务器连接失败");
 throw new exception("session is null,服务器连接失败");
 }else {
 log.info("connected success, ip is ["+ip+"]");
 }
 // 设置登陆主机的密码
 session.setpassword(psw);// 设置密码
 // 设置第一次登陆的时候提示,可选值:(ask | yes | no)
 session.setconfig("stricthostkeychecking", "no");
 // 设置登陆超时时间ms
 session.connect(960);
 try {
 // 创建sftp通信通道
 channel = (channel) session.openchannel("sftp");
 channel.connect(1000);
 channelsftp sftp = (channelsftp) channel;
 // 进入服务器指定的文件夹
 sftp.cd(serverpath);
 // 列出服务器指定的文件列表
// vector v = sftp.ls("*.sh");
// for (int i = 0; i < v.size(); i++) {
// system.out.println(v.get(i));
// }
 // 以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换一下流就可以了
 string[] files = getlocalfilenamearray(localpath);//获取所有文件名数组
 for (int i = 0; i < files.length; i++) {
 string filename = files[i];
 if (fileextension != null && !"".equals(fileextension)) {//如果扩展名不为空,则上传该路径下指定扩展名的文件
  if (filename.endswith(fileextension)) {
  outputstream outstream = sftp.put(filename);//要上传到服务器的文件,可以另外设个名字,也可以用本地的名称
  inputstream instream = new fileinputstream(new file(localpath+"/"+filename));//读取本地文件
  byte b[] = new byte[1024];
  int n;
  while ((n = instream.read(b)) != -1) {
  outstream.write(b, 0, n);
  }
  outstream.flush();
  outstream.close();
  instream.close();
  log.info("文件["+localpath+"/"+filename+"]上传成功!---->>>>上传到目录["+serverpath+"]中.");
  }else {
  log.info("警告:文件["+filename+"]不是指定类型["+fileextension+"]的文件");
  }
 }else {//如果扩展名为空,则上传该路径下的所有文件
  outputstream outstream = sftp.put(filename);//要上传到服务器的文件,可以另外设个名字,也可以用本地的名称
  inputstream instream = new fileinputstream(new file(localpath+"/"+filename));//本地文件
  byte b[] = new byte[1024];
  int n;
  while ((n = instream.read(b)) != -1) {
  outstream.write(b, 0, n);
  }
  outstream.flush();
  outstream.close();
  instream.close();
  log.info("文件["+filename+"]上传成功!---->>>>上传到目录["+serverpath+"]中.");
 }
 }
 } catch (exception e) {
 e.printstacktrace();
 } finally {
 session.disconnect();
 channel.disconnect();
 }
 }
 
 
 /**
  * 利用jsch包实现sftp下载、上传文件(该方法暂不适用)
  * @param ip 主机ip
  * @param user 主机登陆用户名
  * @param psw 主机登陆密码
  * @param port 主机ssh2登陆端口,如果取默认值(默认值22),传-1
  * @param privatekey 密钥文件路径
  * @param passphrase 密钥的密码
  * 
  */
 public static void sshsftp(string ip, string user, string psw ,int port ,string privatekey ,string passphrase) throws exception{
  session session = null;
  channel channel = null;
  jsch jsch = new jsch();
  //设置密钥和密码
  if (privatekey != null && !"".equals(privatekey)) {
   if (passphrase != null && "".equals(passphrase)) {
    //设置带口令的密钥
    jsch.addidentity(privatekey, passphrase);
   } else {
    //设置不带口令的密钥
    jsch.addidentity(privatekey);
   }
  }
  if(port <=0){
   //连接服务器,采用默认端口
   session = jsch.getsession(user, ip);
  }else{
   //采用指定的端口连接服务器
   session = jsch.getsession(user, ip ,port);
  }
  //如果服务器连接不上,则抛出异常
  if (session == null) {
   throw new exception("session is null");
  }
  //设置登陆主机的密码
  session.setpassword(psw);//设置密码 
  //设置第一次登陆的时候提示,可选值:(ask | yes | no)
  session.setconfig("stricthostkeychecking", "no");
  //设置登陆超时时间 
  session.connect(30000);
  try {
   //创建sftp通信通道
   channel = (channel) session.openchannel("sftp");
   channel.connect(1000);
   channelsftp sftp = (channelsftp) channel;
   //进入服务器指定的文件夹
   sftp.cd("domains");
   //列出服务器指定的文件列表
   vector<?> v = sftp.ls("*.txt");
   for(int i=0;i<v.size();i++){
    log.info(v.get(i));
   }
   //以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换以下流就可以了
   outputstream outstream = sftp.put("1.txt");
   inputstream instream = new fileinputstream(new file("c:/print.txt"));
   byte b[] = new byte[1024];
   int n;
   while ((n = instream.read(b)) != -1) {
    outstream.write(b, 0, n);
   }
   outstream.flush();
   outstream.close();
   instream.close();
  } catch (exception e) {
   e.printstacktrace();
  } finally {
   session.disconnect();
   channel.disconnect();
  }
 }
 
 
 //***************utils******************//
 /**
 * 读取指定路径下的所有文件
 * @param localpath 指定路径
 * @return string[] 文件名数组
 */
 public static string[] getlocalfilenamearray(string localpath){
 file diskfile = new file(localpath);
 string[] filenamelist = diskfile.list() ;
 if(filenamelist!=null){
 //按照文件名倒序排序
 arrays.sort(filenamelist,collections.reverseorder()); 
 }
 return filenamelist ;
 }
 
 
 /**
 * 删除指定目录的,指定扩展名的远程文件
 * @param directory 要删除文件的目录
 * @param sftp channelsftp实体
 * @param fileextension 文件扩展名(删除远程文件,扩展名不能为空)
 */
 public void deleteall(string directory, channelsftp sftp, string fileextension) {
  try {
  sftp.cd(directory);
  vector<?> v = null;
  if (fileextension !=null && "".equals(fileextension)) {
  v=sftp.ls("*"+fileextension);
 }else {
// v=sftp.ls("");//此处有风险
 log.warn("fileextension is not null! please check");
 }
  for (int i = 0; i < v.size(); i++) {
  string[] fileinfos = v.get(i).tostring().replaceall("\t", " ").split(" ");
 string filename = fileinfos[fileinfos.length-1];
   sftp.rm(filename);
  }
  } catch (exception e) {
  e.printstacktrace();
  }
 }
 
 /** 
 * 删除单个文件 
 * 
 * @param directory 
 *   要删除文件所在目录 
 * @param deletefile 
 *   要删除的文件 
 * @throws exception  
 */ 
 public static void deleteonefile(string directory, string deletefile, channelsftp sftp) throws exception { 
 sftp.cd(directory); 
 sftp.rm(deletefile); 
 } 
 
 
}

这就是整个工具的内容了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇: 线程池原理解析

下一篇: