利用ssh实现服务器文件上传下载
通过ssh实现服务器文件上传下载
写在前面的话
之前记录过一篇使用apache的FTP开源组件实现服务器文件上传下载的方法,但是后来发现在删除的时候会有些权限问题,导致无法删除服务器上的文件。虽然在Windows上使用FileZillaServer设置读写权限后没问题,但是在服务器端还是有些不好用。
因为自己需要实现资源管理功能,除了单文件的FastDFS存储之外,一些特定资源的存储还是打算暂时存放服务器上,项目组同事说后面不会专门在服务器上开FTP服务,于是改成了sftp方式进行操作。
这个东西要怎么用
首先要去下载jschjar包,地址是:http://www.jcraft.com/jsch/。网站上也写的很清楚:JSchisapureJavaimplementationofSSH2.这个是SSH2的纯Java实现。使用ip和端口,输入用户名密码就可以正常使用了,和SecureCRT使用方式一致。那么怎么来使用这个有用的工具呢?
其实不会写也没关系,官方也给出了示例,链接:http://www.jcraft.com/jsch/examples/Shell.java,来看一眼吧:
/*-*-mode:java;c-basic-offset:2;indent-tabs-mode:nil-*-*/
/**
*Thisprogramenablesyoutoconnecttosshdserverandgettheshellprompt.
*$CLASSPATH=.:../buildjavacShell.java
*$CLASSPATH=.:../buildjavaShell
*Youwillbeaskedusername,hostnameandpasswd.
*Ifeverythingworksfine,youwillgettheshellprompt.Outputmay
*beuglybecauseoflacksofterminal-emulation,butyoucanissuecommands.
*
*/
importcom.jcraft.jsch.*;
importjava.awt.*;
importjavax.swing.*;
publicclassShell{
publicstaticvoidmain(String[]arg){
try{
JSchjsch=newJSch();
//jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
Stringhost=null;
if(arg.length>0){
host=arg[0];
}
else{
host=JOptionPane.showInputDialog("Enterusername@hostname",
System.getProperty("user.name")+
"@localhost");
}
Stringuser=host.substring(0,host.indexOf('@'));
host=host.substring(host.indexOf('@')+1);
Sessionsession=jsch.getSession(user,host,22);
Stringpasswd=JOptionPane.showInputDialog("Enterpassword");
session.setPassword(passwd);
UserInfoui=newMyUserInfo(){
publicvoidshowMessage(Stringmessage){
JOptionPane.showMessageDialog(null,message);
}
publicbooleanpromptYesNo(Stringmessage){
Object[]options={"yes","no"};
intfoo=JOptionPane.showOptionDialog(null,
message,
"Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null,options,options[0]);
returnfoo==0;
}
//IfpasswordisnotgivenbeforetheinvocationofSession#connect(),
//implementalsofollowingmethods,
//*UserInfo#getPassword(),
//*UserInfo#promptPassword(Stringmessage)and
//*UIKeyboardInteractive#promptKeyboardInteractive()
};
session.setUserInfo(ui);
//Itmustnotberecommended,butifyouwanttoskiphost-keycheck,
//invokefollowing,
//session.setConfig("StrictHostKeyChecking","no");
//session.connect();
session.connect(30000);//makingaconnectionwithtimeout.
Channelchannel=session.openChannel("shell");
//Enableagent-forwarding.
//((ChannelShell)channel).setAgentForwarding(true);
channel.setInputStream(System.in);
/*
//ahackforMS-DOSpromptonWindows.
channel.setInputStream(newFilterInputStream(System.in){
publicintread(byte[]b,intoff,intlen)throwsIOException{
returnin.read(b,off,(len>1024?1024:len));
}
});
*/
channel.setOutputStream(System.out);
/*
//Choosethepty-type"vt102".
((ChannelShell)channel).setPtyType("vt102");
*/
/*
//Setenvironmentvariable"LANG"as"ja_JP.eucJP".
((ChannelShell)channel).setEnv("LANG","ja_JP.eucJP");
*/
//channel.connect();
channel.connect(3*1000);
}
catch(Exceptione){
System.out.println(e);
}
}
publicstaticabstractclassMyUserInfo
implementsUserInfo,UIKeyboardInteractive{
publicStringgetPassword(){returnnull;}
publicbooleanpromptYesNo(Stringstr){returnfalse;}
publicStringgetPassphrase(){returnnull;}
publicbooleanpromptPassphrase(Stringmessage){returnfalse;}
publicbooleanpromptPassword(Stringmessage){returnfalse;}
publicvoidshowMessage(Stringmessage){}
publicString[]promptKeyboardInteractive(Stringdestination,
Stringname,
Stringinstruction,
String[]prompt,
boolean[]echo){
returnnull;
}
}
}
在这个代码中,我们基本上能看到需要的东西,首先我们要创建用户信息,这个主要是给认证的时候用的,只要实现UserInfo,UIKeyboardInteractive这两个接口就好了,然后通过创建session会话,将userInfo设置进去,最后进行连接即可。
封装文件上传下载
上面是Jsch的基本使用方法,也就是些基本套路。下面我们来自己封装一下自己要使用的功能,实现文件的上传下载等一系列操作。
首先,也来创建个UserInfo:
publicclassMyUserInfoimplementsUserInfo,UIKeyboardInteractive{
publicStringgetPassword(){returnnull;}
publicbooleanpromptYesNo(Stringstr){
returntrue;
}
publicStringgetPassphrase(){returnnull;}
publicbooleanpromptPassphrase(Stringmessage){returntrue;}
publicbooleanpromptPassword(Stringmessage){
returntrue;
}
publicvoidshowMessage(Stringmessage){
}
@Override
publicString[]promptKeyboardInteractive(Stringarg0,Stringarg1,
Stringarg2,String[]arg3,boolean[]arg4){
returnnull;
}
}
下面是实现类:
packagecom.tfxiaozi.common.utils;
importjava.io.InputStream;
importjava.util.ArrayList;
importjava.util.Iterator;
importjava.util.List;
importjava.util.Vector;
importorg.apache.log4j.Logger;
importcom.jcraft.jsch.Channel;
importcom.jcraft.jsch.ChannelExec;
importcom.jcraft.jsch.ChannelSftp;
importcom.jcraft.jsch.JSch;
importcom.jcraft.jsch.JSchException;
importcom.jcraft.jsch.Session;
importcom.jcraft.jsch.SftpException;
importcom.jcraft.jsch.SftpProgressMonitor;
/**
*SSHUtils
*@authortfxiaozi
*
*/
publicclassSsh{
Loggerlogger=Logger.getLogger(this.getClass());
privateStringhost="";
privateStringuser="";
privateintport=22;
privateStringpassword="";
privatestaticfinalStringPROTOCOL="sftp";
JSchjsch=newJSch();
privateSessionsession;
privateChannelchannel;
privateChannelSftpsftp;
publicStringgetHost(){
returnhost;
}
publicvoidsetHost(Stringhost){
this.host=host;
}
publicStringgetUser(){
returnuser;
}
publicvoidsetUser(Stringuser){
this.user=user;
}
publicSsh(){
}
publicSsh(Stringhost,intport,Stringuser,Stringpassword){
this.host=host;
this.user=user;
this.password=password;
this.port=port;
}
/**
*connectssh
*@throwsJSchException
*/
publicvoidconnect()throwsJSchException{
if(session==null){
session=jsch.getSession(user,host,port);
MyUserInfoui=newMyUserInfo();
session.setUserInfo(ui);
session.setPassword(password);
session.connect();
channel=session.openChannel(PROTOCOL);
channel.connect();
sftp=(ChannelSftp)channel;
}
}
/**
*disconnectssh
*/
publicvoiddisconnect(){
if(session!=null){
session.disconnect();
session=null;
}
}
/**
*upload
*@paramlocalFileName
*@paramremoteFileName
*@return
*/
publicbooleanupload(StringlocalFileName,StringremoteFileName)throwsException{
booleanbSucc=false;
try{
SftpProgressMonitormonitor=newMyProgressMonitor();
intmode=ChannelSftp.OVERWRITE;
sftp.put(localFileName,remoteFileName,monitor,mode);
bSucc=true;
}catch(Exceptione){
logger.error(e);
}finally{
if(null!=channel){
channel.disconnect();
}
}
returnbSucc;
}
/**
*deletefile
*@paramdirectory
*@paramfileName
*@return
*/
publicbooleandeteleFile(Stringdirectory,StringfileName){
booleanflag=false;
try{
sftp.cd(directory);
sftp.rm(fileName);
flag=true;
}catch(SftpExceptione){
flag=false;
logger.error(e);
}
returnflag;
}
/**
*deletedirectory
*@paramdirectorydirtobedelete
*@paramsurebesuretodelete
*@return
*/
publicStringdeleteDir(Stringdirectory,booleansure){
Stringcommand="rm-rf"+directory;
Stringresult=execCommand(command,true);
returnresult;
}
/**
*compressthefilesandsub-dirofdirectoryintoazipnamedcompressName
*@paramdirectorythecontentdirectorytobecompress
*@paramcompressNamethenameindirectoryafteritiscompressed
*@throwsSftpException
*@usagessh.compressDir("/home/tfxiaozi/webapp","test.zip");
*/
publicvoidcompressDir(Stringdirectory,StringcompressName)throwsSftpException{
Stringcommand="cd"+directory+"\nzip-r"+compressName+"./"+compressName.substring(0,compressName.lastIndexOf("."));
execCommand(command,true);
}
/**
*download
*@paramlocalFileName
*@paramremoteFileName
*@return
*/
publicbooleandownload(StringlocalFileName,StringremoteFileName){
booleanbSucc=false;
Channelchannel=null;
try{
SftpProgressMonitormonitor=newMyProgressMonitor();
sftp.get(remoteFileName,localFileName,monitor,ChannelSftp.OVERWRITE);
bSucc=true;
}catch(Exceptione){
logger.error(e);
}finally{
if(null!=channel){
channel.disconnect();
}
}
returnbSucc;
}
/**
*executecommand
*@paramcommand
*@paramflag
*@return
*/
publicStringexecCommand(Stringcommand,booleanflag){
Channelchannel=null;
InputStreamin=null;
StringBuffersb=newStringBuffer("");
try{
channel=session.openChannel("exec");
System.out.println("command:"+command);
((ChannelExec)channel).setCommand("exportTERM=ansi&&"+command);
((ChannelExec)channel).setErrStream(System.err);
in=channel.getInputStream();
channel.connect();
if(flag){
byte[]tmp=newbyte[10240];
while(true){
while(in.available()>0){
inti=in.read(tmp,0,10240);
if(i<0){
break;
}
sb.append(newString(tmp,0,i));
}
if(channel.isClosed()){
break;
}
}
}
in.close();
}catch(Exceptione){
logger.error(e);
}finally{
if(channel!=null){
channel.disconnect();
}
}
returnsb.toString();
}
/**
*getcpuinfo
*@return
*/
publicString[]getCpuInfo(){
Channelchannel=null;
InputStreamin=null;
StringBuffersb=newStringBuffer("");
try{
channel=session.openChannel("exec");
((ChannelExec)channel).setCommand("exportTERM=ansi&&top-bn1");//ansi一定要加
in=channel.getInputStream();
((ChannelExec)channel).setErrStream(System.err);
channel.connect();
byte[]tmp=newbyte[10240];
while(true){
while(in.available()>0){
inti=in.read(tmp,0,10240);
if(i<0){
break;
}
sb.append(newString(tmp,0,i));
}
if(channel.isClosed()){
break;
}
}
}catch(Exceptione){
logger.error(e);
}finally{
if(channel!=null){
channel.disconnect();
}
}
Stringbuf=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(""," ");
returnbuf.split("\\n");
}
/**
*getharddiskinfo
*@return
*/
publicStringgetHardDiskInfo()throwsException{
Channelchannel=null;
InputStreamin=null;
StringBuffersb=newStringBuffer("");
try{
channel=session.openChannel("exec");
((ChannelExec)channel).setCommand("df-lh");
in=channel.getInputStream();
((ChannelExec)channel).setErrStream(System.err);
channel.connect();
byte[]tmp=newbyte[10240];
while(true){
while(in.available()>0){
inti=in.read(tmp,0,10240);
if(i<0){
break;
}
sb.append(newString(tmp,0,i));
}
if(channel.isClosed()){
break;
}
}
}catch(Exceptione){
thrownewRuntimeException(e);
}finally{
if(channel!=null){
channel.disconnect();
}
}
Stringbuf=sb.toString();
String[]info=buf.split("\n");
if(info.length>2){//firstline:FilesystemSizeUsedAvailUse%Mountedon
Stringtmp="";
for(inti=1;i<info.length;i++){
tmp=info[i];
String[]tmpArr=tmp.split("%");
if(tmpArr[1].trim().equals("/")){
booleanflag=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="";
}
returnbuf;
}
/**
*返回空闲字节数
*@return
*@throwsException
*/
publicdoublegetFreeDisk()throwsException{
StringhardDiskInfo=getHardDiskInfo();
if(hardDiskInfo==null||hardDiskInfo.equals("")){
logger.error("getfreeharddiskspacefailed.....");
return-1;
}
String[]diskInfo=hardDiskInfo.replace("","").split(",");
if(diskInfo==null||diskInfo.length==0){
logger.error("getfreediskinfofailed.........");
return-1;
}
Stringfree=diskInfo[2];
free=free.substring(0,free.indexOf("free"));
//System.out.println("freespace:"+free);
Stringunit=free.substring(free.length()-1);
//System.out.println("unit:"+unit);
StringfreeSpace=free.substring(0,free.length()-1);
doublefreeSpaceL=Double.parseDouble(freeSpace);
//System.out.println("freespaceL:"+freeSpaceL);
if(unit.equals("K")){
returnfreeSpaceL*1024;
}elseif(unit.equals("M")){
returnfreeSpaceL*1024*1024;
}elseif(unit.equals("G")){
returnfreeSpaceL*1024*1024*1024;
}elseif(unit.equals("T")){
returnfreeSpaceL*1024*1024*1024*1024;
}elseif(unit.equals("P")){
returnfreeSpaceL*1024*1024*1024*1024*1024;
}
return0;
}
/**
*获取指定目录下的所有子目录及文件
*@paramdirectory
*@return
*@throwsException
*/
@SuppressWarnings("rawtypes")
publicList<String>listFiles(Stringdirectory)throwsException{
VectorfileList=null;
List<String>fileNameList=newArrayList<String>();
fileList=sftp.ls(directory);
Iteratorit=fileList.iterator();
while(it.hasNext()){
StringfileName=((ChannelSftp.LsEntry)it.next()).getFilename();
if(fileName.startsWith(".")||fileName.startsWith("..")){
continue;
}
fileNameList.add(fileName);
}
returnfileNameList;
}
publicbooleanmkdir(Stringpath){
booleanflag=false;
try{
sftp.mkdir(path);
flag=true;
}catch(SftpExceptione){
flag=false;
}
returnflag;
}
}
测试一下
publicstaticvoidmain(String[]arg)throwsException{
Sshssh=newSsh("10.10.10.83",22,"test","test");
try{
ssh.connect();
}catch(JSchExceptione){
e.printStackTrace();
}
/*StringremotePath="/home/tfxiaozi/"+"webapp/";
try{
ssh.listFiles(remotePath);
}catch(Exceptione){
ssh.mkdir(remotePath);
}*/
/*booleanb=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(Strings:list){
System.out.println(s);
}*/
/*booleanb=ssh.deteleFile("webapp","test.zip");
System.out.println(b);*/
/*try{
Strings=ssh.execCommand("ls-l/home/tfxiaozi/webapp1/test",true);
System.out.println(s);
}catch(Exceptione){
System.out.println(e.getMessage());
}*/
//ssh.sftp.setFilenameEncoding("UTF-8");
/*try{
Stringss=ssh.execCommand("unzip/home/tfxiaozi/webapp1/test.zip-d/home/tfxiaozi/webapp1/",true);
System.out.println(ss);
}catch(Exceptione){
System.out.println(e.getMessage());
}*/
/*Stringpath="/home/tfxiaozi/webapp1/test.zip";
try{
List<String>list=ssh.listFiles(path);
for(Strings:list){
System.out.println(s);
}
System.out.println("ok");
}catch(Exceptione){
System.out.println("extractfailed....");
}*/
/*Stringcommand="rm-rf/home/tfxiaozi/webapp1/"+"水墨国学";
Stringsss=ssh.execCommand(command,true);
System.out.println(sss);*/
/*StringfindCommand="find/home/tfxiaozi/webapp1/水墨国学-name'index.html'";
Stringresult=ssh.execCommand(findCommand,true);
System.out.println(result);*/
/*Stringpath="";
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");
/*booleanb=ssh.download("d:/temp/test.zip","webapp/test.zip");
System.out.println(b);*/
//ssh.getHardDiskInfo();
System.out.println(ssh.getFreeDisk());
ssh.disconnect();
}
以上就是直接使用linux方式进行操作,不过需要注意的是,对于中文文件,在解压的时候,传入的时候会有可能乱码,需要加上参数,如unzip-Ocp936test.zip-d/home/tfxiaozi/test。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。