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

网友投稿 316 2023-07-06


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

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

写在前面的话

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

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

这个东西要怎么用

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

其实不会写也没关系,官方也给出了示例,链接:http://jcraft.com/jsch/examples/Shell.java,来看一眼吧:

/* -*-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(http://);

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 RjdOVWtdirectory, 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 = RjdOVWtbuf.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 listFiles(String directory) throws Exception {

Vector fileList = null;

List fileNameList = new ArrayList();

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 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 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 'index.html'";

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。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Guava
下一篇:详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
相关文章

 发表评论

暂时没有评论,来抢沙发吧~