当前位置: 移动技术网 > IT编程>开发语言>Java > 利用ssh实现服务器文件上传下载

利用ssh实现服务器文件上传下载

2019年07月22日  | 移动技术网IT编程  | 我要评论

傲世重生txt下载,宋小宝小品全集,语言栏不显示

通过ssh实现服务器文件上传下载

写在前面的话

之前记录过一篇使用apache的ftp开源组件实现服务器文件上传下载的方法,但是后来发现在删除的时候会有些权限问题,导致无法删除服务器上的文件。虽然在windows上使用filezilla server设置读写权限后没问题,但是在服务器端还是有些不好用。

因为自己需要实现资源管理功能,除了单文件的fastdfs存储之外,一些特定资源的存储还是打算暂时存放服务器上,项目组同事说后面不会专门在服务器上开ftp服务,于是改成了sftp方式进行操作。

这个东西要怎么用

首先要去下载jsch jar包,地址是:http://www.jcraft.com/jsch/。网站上也写的很清楚:jsch is a pure java implementation of ssh2. 这个是ssh2的纯java实现。使用ip和端口,输入用户名密码就可以正常使用了,和secure crt使用方式一致。那么怎么来使用这个有用的工具呢?

其实不会写也没关系,官方也给出了示例,链接:,来看一眼吧:

/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/**
 * this program enables you to connect to sshd server and get the shell prompt.
 * $ classpath=.:../build javac shell.java 
 * $ classpath=.:../build java shell
 * you will be asked username, hostname and passwd. 
 * if everything works fine, you will get the shell prompt. output may
 * be ugly because of lacks of terminal-emulation, but you can issue commands.
 *
 */
import com.jcraft.jsch.*;
import java.awt.*;
import javax.swing.*;

public class shell{
 public static void main(string[] arg){

 try{
  jsch jsch=new jsch();

  //jsch.setknownhosts("/home/foo/.ssh/known_hosts");

  string host=null;
  if(arg.length>0){
  host=arg[0];
  }
  else{
  host=joptionpane.showinputdialog("enter username@hostname",
           system.getproperty("user.name")+
           "@localhost"); 
  }
  string user=host.substring(0, host.indexof('@'));
  host=host.substring(host.indexof('@')+1);

  session session=jsch.getsession(user, host, 22);

  string passwd = joptionpane.showinputdialog("enter password");
  session.setpassword(passwd);

  userinfo ui = new myuserinfo(){
  public void showmessage(string message){
   joptionpane.showmessagedialog(null, message);
  }
  public boolean promptyesno(string message){
   object[] options={ "yes", "no" };
   int foo=joptionpane.showoptiondialog(null, 
            message,
            "warning", 
            joptionpane.default_option, 
            joptionpane.warning_message,
            null, options, options[0]);
   return foo==0;
  }

  // if password is not given before the invocation of session#connect(),
  // implement also following methods,
  // * userinfo#getpassword(),
  // * userinfo#promptpassword(string message) and
  // * uikeyboardinteractive#promptkeyboardinteractive()

  };

  session.setuserinfo(ui);

  // it must not be recommended, but if you want to skip host-key check,
  // invoke following,
  // session.setconfig("stricthostkeychecking", "no");

  //session.connect();
  session.connect(30000); // making a connection with timeout.

  channel channel=session.openchannel("shell");

  // enable agent-forwarding.
  //((channelshell)channel).setagentforwarding(true);

  channel.setinputstream(system.in);
  /*
  // a hack for ms-dos prompt on windows.
  channel.setinputstream(new filterinputstream(system.in){
   public int read(byte[] b, int off, int len)throws ioexception{
   return in.read(b, off, (len>1024?1024:len));
   }
  });
  */

  channel.setoutputstream(system.out);

  /*
  // choose the pty-type "vt102".
  ((channelshell)channel).setptytype("vt102");
  */

  /*
  // set environment variable "lang" as "ja_jp.eucjp".
  ((channelshell)channel).setenv("lang", "ja_jp.eucjp");
  */

  //channel.connect();
  channel.connect(3*1000);
 }
 catch(exception e){
  system.out.println(e);
 }
 }

 public static abstract class myuserinfo
       implements userinfo, uikeyboardinteractive{
 public string getpassword(){ return null; }
 public boolean promptyesno(string str){ return false; }
 public string getpassphrase(){ return null; }
 public boolean promptpassphrase(string message){ return false; }
 public boolean promptpassword(string message){ return false; }
 public void showmessage(string message){ }
 public string[] promptkeyboardinteractive(string destination,
            string name,
            string instruction,
            string[] prompt,
            boolean[] echo){
  return null;
 }
 }
}

在这个代码中,我们基本上能看到需要的东西,首先我们要创建用户信息,这个主要是给认证的时候用的,只要实现 userinfo, uikeyboardinteractive这两个接口就好了,然后通过创建session会话,将userinfo设置进去,最后进行连接即可。

封装文件上传下载

上面是jsch的基本使用方法,也就是些基本套路。下面我们来自己封装一下自己要使用的功能,实现文件的上传下载等一系列操作。

首先,也来创建个userinfo:

public class myuserinfo implements userinfo, uikeyboardinteractive{
 public string getpassword(){ return null; }
 public boolean promptyesno(string str){
  return true;
 }
 public string getpassphrase(){ return null; }
 public boolean promptpassphrase(string message){ return true; }
 public boolean promptpassword(string message){
  return true;
 }
 public void showmessage(string message){
 }
 @override
 public string[] promptkeyboardinteractive(string arg0, string arg1,
   string arg2, string[] arg3, boolean[] arg4) {
  return null;
 }
}

下面是实现类:

package com.tfxiaozi.common.utils;

import java.io.inputstream;
import java.util.arraylist;
import java.util.iterator;
import java.util.list;
import java.util.vector;

import org.apache.log4j.logger;

import com.jcraft.jsch.channel;
import com.jcraft.jsch.channelexec;
import com.jcraft.jsch.channelsftp;
import com.jcraft.jsch.jsch;
import com.jcraft.jsch.jschexception;
import com.jcraft.jsch.session;
import com.jcraft.jsch.sftpexception;
import com.jcraft.jsch.sftpprogressmonitor;
/**
 * ssh utils
 * @author tfxiaozi
 *
 */
public class ssh {
 logger logger = logger.getlogger(this.getclass());
 private string host = "";
 private string user = "";
 private int port = 22; 
 private string password = "";
 private static final string protocol = "sftp";
 jsch jsch = new jsch();
 private session session;
 private channel channel;
 private channelsftp sftp;

 public string gethost() {
  return host;
 }

 public void sethost(string host) {
  this.host = host;
 }

 public string getuser() {
  return user;
 }

 public void setuser(string user) {
  this.user = user;
 }

 public ssh() {
 }

 public ssh(string host, int port, string user, string password) {
  this.host = host;
  this.user = user;
  this.password = password;
  this.port = port;
 }

 /**
  * connect ssh
  * @throws jschexception
  */
 public void connect() throws jschexception {
  if (session == null) {
   session = jsch.getsession(user, host, port);
   myuserinfo ui = new myuserinfo();
   session.setuserinfo(ui);
   session.setpassword(password);
   session.connect();
   channel = session.openchannel(protocol);
   channel.connect();
   sftp = (channelsftp)channel;
  }
 }

 /**
  * disconnect ssh
  */
 public void disconnect() {
  if (session != null) {
   session.disconnect();
   session = null;
  }
 }

 /**
  * upload
  * @param localfilename
  * @param remotefilename
  * @return
  */
 public boolean upload(string localfilename, string remotefilename) throws exception{
  boolean bsucc = false;
  try {
   sftpprogressmonitor monitor=new myprogressmonitor();
   int mode=channelsftp.overwrite;
   sftp.put(localfilename, remotefilename, monitor, mode); 
   bsucc = true;
  } catch(exception e) {
   logger.error(e);
  } finally {
   if (null != channel) {
    channel.disconnect();
   }
  }
  return bsucc;
 }

 /**
  * delete file
  * @param directory
  * @param filename
  * @return
  */
 public boolean detelefile(string directory, string filename) {
  boolean flag = false;
  try {
   sftp.cd(directory);
   sftp.rm(filename);
   flag = true;
  } catch (sftpexception e) {
   flag = false;
   logger.error(e);
  }
  return flag;
 }

 /**
  * delete directory
  * @param directory dir to be delete
  * @param sure be sure to delete
  * @return
  */
 public string deletedir(string directory, boolean sure) {
  string command = "rm -rf " + directory;
  string result = execcommand(command, true);
  return result;
 }

 /**
  * compress the files and sub-dir of directory into a zip named compressname
  * @param directory the content directory to be compress
  * @param compressname the name in directory after it is compressed
  * @throws sftpexception 
  * @usage ssh.compressdir("/home/tfxiaozi/webapp", "test.zip");
  */
 public void compressdir(string directory, string compressname) throws sftpexception {
  string command = "cd "+ directory +"\nzip -r " + compressname + " ./" + compressname.substring(0, compressname.lastindexof("."));
  execcommand(command, true);
 }


 /**
  * download
  * @param localfilename
  * @param remotefilename
  * @return
  */
 public boolean download(string localfilename, string remotefilename) {
  boolean bsucc = false;
  channel channel = null;
  try {
   sftpprogressmonitor monitor = new myprogressmonitor();
   sftp.get(remotefilename, localfilename, monitor, channelsftp.overwrite); 
   bsucc = true;
  } catch(exception e) {
   logger.error(e);
  } finally {
   if (null != channel) {
    channel.disconnect();
   }
  }
  return bsucc;
 }

 /**
  * execute command
  * @param command
  * @param flag
  * @return
  */
 public string execcommand(string command, boolean flag) {
  channel channel = null;
  inputstream in = null;
  stringbuffer sb = new stringbuffer("");
  try {
   channel = session.openchannel("exec");
   system.out.println("command:" + command);
   ((channelexec)channel).setcommand("export term=ansi && " + command);
   ((channelexec)channel).seterrstream(system.err);
   in = channel.getinputstream();
   channel.connect();
   if (flag) {
    byte[] tmp = new byte[10240];
    while (true) {
     while (in.available()>0) {
      int i = in.read(tmp, 0, 10240);
      if(i < 0) {
       break;
      }
      sb.append(new string(tmp, 0, i));
     }
     if (channel.isclosed()){
      break;
     }
    }
   }
   in.close();
  } catch(exception e){
   logger.error(e);
  } finally {
   if (channel != null) {
    channel.disconnect();
   }
  }
  return sb.tostring();
 }

 /**
  * get cpu info
  * @return
  */
 public string[] getcpuinfo() {
  channel channel = null;
  inputstream in = null;
  stringbuffer sb = new stringbuffer("");
  try {
   channel = session.openchannel("exec");
   ((channelexec)channel).setcommand("export term=ansi && top -bn 1");//ansi一定要加
   in = channel.getinputstream();
   ((channelexec)channel).seterrstream(system.err);
   channel.connect();
   byte[] tmp = new byte[10240];
   while (true) {
    while (in.available()>0) {
     int i = in.read(tmp, 0, 10240);
     if(i < 0) {
      break;
     }
     sb.append(new string(tmp, 0, i));
    }
    if (channel.isclosed()){
     break;
    }
   }
  } catch(exception e){
   logger.error(e);
  } finally {
   if (channel != null) {
    channel.disconnect();
   }
  }
  string buf = sb.tostring();
  if (buf.indexof("swap") != -1) {
   buf = buf.substring(0, buf.indexof("swap"));
  }
  if (buf.indexof("cpu") != -1) {
   buf = buf.substring(buf.indexof("cpu"), buf.length());
  }
  buf.replaceall(" ", " ");
  return buf.split("\\n");
 }

 /**
  * get hard disk info
  * @return
  */
 public string getharddiskinfo() throws exception{
  channel channel = null;
  inputstream in = null;
  stringbuffer sb = new stringbuffer("");
  try {
   channel = session.openchannel("exec");
   ((channelexec)channel).setcommand("df -lh");
   in = channel.getinputstream();
   ((channelexec)channel).seterrstream(system.err);
   channel.connect();

   byte[] tmp = new byte[10240];
   while (true) {
    while (in.available()>0) {
     int i = in.read(tmp, 0, 10240);
     if(i < 0) {
      break;
     }
     sb.append(new string(tmp, 0, i));
    }
    if (channel.isclosed()){
     break;
    }
   }
  } catch(exception e){
   throw new runtimeexception(e);
  } finally {
   if (channel != null) {
    channel.disconnect();
   }
  }
  string buf = sb.tostring();
  string[] info = buf.split("\n");
  if(info.length > 2) {//first line: filesystem size used avail use% mounted on
   string tmp = "";
   for(int i=1; i< info.length; i++) {
    tmp = info[i];
    string[] tmparr = tmp.split("%");
    if(tmparr[1].trim().equals("/")){
     boolean flag = true;
     while(flag) {
      tmp = tmp.replaceall(" ", " ");
      if (tmp.indexof(" ") == -1){
       flag = false;
      }
     }

     string[] result = tmp.split(" ");
     if(result != null && result.length == 6) {
      buf = result[1] + " total, " + result[2] + " used, " + result[3] + " free";
      break;
     } else {
      buf = "";
     }
    }
   }
  } else {
   buf = "";
  }
  return buf;
 }

 /**
  * 返回空闲字节数
  * @return
  * @throws exception 
  */
 public double getfreedisk() throws exception {
  string harddiskinfo = getharddiskinfo();
  if(harddiskinfo == null || harddiskinfo.equals("")) {
   logger.error("get free harddisk space failed.....");
   return -1;
  }
  string[] diskinfo = harddiskinfo.replace(" ", "").split(",");
  if(diskinfo == null || diskinfo.length == 0) {
   logger.error("get free disk info failed.........");
   return -1;
  }
  string free = diskinfo[2];
  free = free.substring(0, free.indexof("free"));
  //system.out.println("free space:" + free);
  string unit = free.substring(free.length()-1);
  //system.out.println("unit:" + unit);
  string freespace = free.substring(0, free.length()-1);
  double freespacel = double.parsedouble(freespace);
  //system.out.println("free spacel:" + freespacel);
  if(unit.equals("k")) {
   return freespacel*1024;
  }else if(unit.equals("m")) {
   return freespacel*1024*1024;
  } else if(unit.equals("g")) {
   return freespacel*1024*1024*1024;
  } else if(unit.equals("t")) {
   return freespacel*1024*1024*1024*1024;
  } else if(unit.equals("p")) {
   return freespacel*1024*1024*1024*1024*1024;
  }
  return 0;
 }

 /**
  * 获取指定目录下的所有子目录及文件
  * @param directory
  * @return
  * @throws exception
  */
 @suppresswarnings("rawtypes")
 public list<string> listfiles(string directory) throws exception {
  vector filelist = null;
  list<string> filenamelist = new arraylist<string>();
  filelist = sftp.ls(directory);
  iterator it = filelist.iterator();
  while (it.hasnext()) {
   string filename = ((channelsftp.lsentry) it.next()).getfilename();
   if (filename.startswith(".") || filename.startswith("..")) {
    continue;
   }
   filenamelist.add(filename);
  }
  return filenamelist;
 }

 public boolean mkdir(string path) {
  boolean flag = false;
  try {
   sftp.mkdir(path);
   flag = true;
  } catch (sftpexception e) {
   flag = false;
  }
  return flag;
 }
}

测试一下

public static void main(string[] arg) throws exception{
  ssh ssh = new ssh("10.10.10.83", 22, "test", "test");
  try {
   ssh.connect();
  } catch (jschexception e) {
   e.printstacktrace();
  }

  /*string remotepath = "/home/tfxiaozi/" + "webapp/";
  try {
   ssh.listfiles(remotepath);
  } catch (exception e) {
   ssh.mkdir(remotepath);
  }*/


  /*boolean b = ssh.upload("d:/test.zip", "webapp/");
  system.out.println(b);*/


  //string []buf = ssh.getcpuinfo();
  //system.out.println("cpu:" + buf[0]);
  //system.out.println("memo:" + buf[1]);
  //system.out.println(ssh.getharddiskinfo().replace(" ", ""));
  //system.out.println(ssh.getfreedisk());


  /*list<string> list = ssh.listfiles("webapp/test");
  for(string s : list) {
   system.out.println(s);
  }*/

  /*boolean b = ssh.detelefile("webapp", "test.zip");
  system.out.println(b);*/


  /*try {
   string s = ssh.execcommand("ls -l /home/tfxiaozi/webapp1/test", true);
   system.out.println(s);
  } catch (exception e) {
   system.out.println(e.getmessage());
  }*/
  //ssh.sftp.setfilenameencoding("utf-8");

  /*try {
   string ss = ssh.execcommand("unzip /home/tfxiaozi/webapp1/test.zip -d /home/tfxiaozi/webapp1/", true);
   system.out.println(ss);
  } catch (exception e) {
   system.out.println( e.getmessage());
  }*/


  /*string path = "/home/tfxiaozi/webapp1/test.zip";
  try {
   list<string> list = ssh.listfiles(path);
   for(string s:list) {
    system.out.println(s);
   }
   system.out.println("ok");
  } catch (exception e) {
   system.out.println("extract failed....");
  }*/


  /*string command = "rm -rf /home/tfxiaozi/webapp1/" + "水墨国学";
  string sss = ssh.execcommand(command, true);
  system.out.println(sss);*/

  /*string findcommand = "find /home/tfxiaozi/webapp1/水墨国学 -name ''";
  string result = ssh.execcommand(findcommand, true);
  system.out.println(result);*/

  /*string path = "";
  ssh.listfiles(remotepath);*/

  /*
  ssh.deletedir("/home/tfxiaozi/webapp1", true);
   */

  //下面这个会解压到webapp1目录,webapp1/test/xxx
  //ssh.execcommand("unzip /home/tfxiaozi/webapp1/test.zip -d /home/tfxiaozi/webapp1", true);
  //下面这个会解压到/webapp1/test目录,也是webapp1/test/test/xxx
  //ssh.execcommand("unzip /home/tfxiaozi/webapp1/test.zip -d /home/tfxiaozi/webapp1", true);

  //ssh.compressdir("/home/tfxiaozi/webapp1", "test.zip");

  //ssh.sftp.cd("/home/tfxiaozi/webapp1");
  //ssh.compressdir("/home/tfxiaozi/webapp1", "test.zip");

  /*boolean b = ssh.download("d:/temp/test.zip", "webapp/test.zip");
  system.out.println(b);*/
  //ssh.getharddiskinfo();
  system.out.println(ssh.getfreedisk());
  ssh.disconnect();
 }

以上就是直接使用linux方式进行操作,不过需要注意的是,对于中文文件,在解压的时候,传入的时候会有可能乱码,需要加上参数,如unzip -o cp936 test.zip -d /home/tfxiaozi/test。

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网