SSH를 통해 서버 파일 업로드 및 다운로드
앞쪽에 쓰여진 단어
이전에 Apache의 FTP 오픈 소스 구성 요소를 사용하여 서버 파일을 업로드하고 다운로드하는 메소드를 기록했지만 나중에 삭제할 때 허가 문제가 있음을 발견하여 서버에서 파일을 삭제할 수 없게됩니다. Windows에서 FileZilla 서버를 사용하여 읽기 및 쓰기 권한을 설정 한 후에는 문제가 없지만 서버 측에서 사용하기가 약간 어렵습니다.
자원 관리 기능을 구현해야하기 때문에 단일 파일의 FASTDFS 스토리지 외에도 특정 리소스의 스토리지는 여전히 서버에 일시적으로 저장 될 계획입니다. 프로젝트 팀 동료들은 나중에 서버에서 특히 FTP 서비스를 열지 않을 것이라고 말했다. 그래서 그들은 SFTP 모드로 변경하여 작동했다.
이 물건을 사용하는 방법
먼저 JSCH JAR 패키지를 다운로드해야합니다. 주소는 http://www.jcraft.com/jsch/입니다. 웹 사이트는 또한 매우 명확하게 씁니다. JSCH는 SSH2의 순수한 Java 구현입니다. 이것은 SSH2의 순수한 Java 구현입니다. IP와 포트를 사용하고 사용자 이름과 비밀번호를 입력하면 보안 CRT의 사용 방법과 동일한 정상적으로 사용할 수 있습니다. 그렇다면이 유용한 도구를 어떻게 사용합니까?
실제로 글을 쓸 수없는 경우에는 중요하지 않습니다. 관계자는 또한 예를 들었다. 링크는 http://www.jcraft.com/jsch/examples/shell.java입니다. 살펴 보겠습니다.
/* -* -모드 : Java; C- 기본 오프셋 : 2; Indent-Tabs-Mode : nil-*-*// ***이 프로그램을 사용하면 SSHD 서버에 연결하고 쉘 프롬프트를 얻을 수 있습니다. * $ classPath =. : ../ 빌드 javac shell.java * $ classpath =. : ../ Java Shell 빌드 * 사용자 이름, 호스트 이름 및 passwd가 요청됩니다. * 모든 것이 잘 작동하면 쉘 프롬프트가 나타납니다. 터미널 배출이 없기 때문에 출력은 추악 할 수 있지만 명령을 발행 할 수 있습니다. **/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 "); 문자열 호스트 = null; if (arg.length> 0) {host = arg [0]; } else {host = joptionpane.showInputDialog ( "ender@hostname enther@hostname", system.getProperty ( "user.name")+ "@localhost"); } string user = host.SubString (0, host.indexof ( '@')); host = host.substring (host.indexof ( '@')+1); 세션 세션 = jsch.getSession (사용자, 호스트, 22); String Passwd = joptionpane.showinputDialog ( "암호를 입력"); 세션 .setpassword (passwd); userInfo ui = new myuserInfo () {public void showmessage (문자열 메시지) {joptionpane.showmessagedialog (null, message); } public boolean prompteyesno (문자열 메시지) {object [] 옵션 = { "yes", "no"}; int foo = joptionpane.showoptionDialog (null, 메시지, "경고", joptionpane.default_option, joptionpane.warning_message, null, 옵션, 옵션 [0]); 반환 foo == 0; } // 세션#connect ()의 호출 전에 비밀번호가 제공되지 않은 경우 // 다음 메소드도 구현합니다. SESSION.SETUSERINFO (UI); // 권장하지 않아야하지만 호스트 키 확인을 건너 뛰려면 // 다음을 호출하려면 // session.setConfig ( "StricThostKeyChecking", "no"); //session.connect (); 세션 .connect (30000); // 타임 아웃과 연결합니다. 채널 채널 = session.openchannel ( "쉘"); // 에이전트 포워드를 활성화합니다. //((CHANNELSHELL)CHANNING).SetAgentForwarding(true); Channel.setInputStream (System.In); /* // Windows에서 MS-DOS 프롬프트를위한 해킹. channel.setInputStream (system.in) {public int read (byte [] b, int off, int len)는 ioexception {return in.read (b, off, (len> 1024? 1024 : len));}}); */ Channel.setOutputStream (System.out); /* // PTY 유형 "vt102"를 선택하십시오. ((채널 쉘) 채널) .setptytype ( "vt102"); * / /* // 환경 변수 "lang"을 "ja_jp.eucjp"로 설정합니다. ((채널 쉘) 채널) .setenv ( "lang", "ja_jp.eucjp"); *///channel.connect (); channel.connect (3*1000); } catch (예외 e) {System.out.println (e); }} public static acblack class myuserinfo userInfo, uikeyboardinteractive {public string getpassword () {return null; } public boolean prompteyesno (string str) {return false; } public String getPassPhrase () {return null; } public boolean prompspassphrase (문자열 메시지) {return false; } public boolean prompspassword (문자열 메시지) {return false; } public void showmessage (문자열 메시지) {} public String [] PrfustKeyboardInteractive (문자열 대상, 문자열 이름, 문자열 명령, 문자열 [] 프롬프트, 부울 [] echo) {return null; }}}이 코드에서는 기본적으로 필요한 것을 볼 수 있습니다. 먼저 사용자 정보를 만들어야합니다. 이것은 주로 인증에 사용됩니다. userInfo와 uikeyboardinteractive의 두 인터페이스 만 구현하십시오. 그런 다음 세션 세션을 만들어 userInfo를 설정하고 최종적으로 연결하십시오.
캡슐화 된 파일 업로드 및 다운로드
위는 JSCH의 기본 사용 방법, 즉 몇 가지 기본 루틴입니다. 사용하려는 기능을 캡슐화하고 파일 업로드 및 다운로드와 같은 일련의 작업을 구현하겠습니다.
먼저 userInfo를 만듭니다.
공개 클래스 myuserinfo userinfo, uikeyboardinteractive {public string getpassword () {return null; } public boolean prompteyesno (String str) {return true; } public String getPassPhrase () {return null; } public boolean prompspassphrase (문자열 메시지) {return true; } public boolean prompspassword (문자열 메시지) {return true; } public void showmessage (문자열 메시지) {} @override public String [] PrfustKeyboardinteractive (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.jsch.channal; 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.sftpprogrestmonitor;/** import Com.jsch.jsch.session; @author tfxiaozi * */public class ssh {logger logger = logger.getLogger (this.getClass ()); 개인 문자열 호스트 = ""; 개인 문자열 user = ""; 개인 int 포트 = 22; 개인 문자열 비밀번호 = ""; 개인 정적 최종 문자열 프로토콜 = "SFTP"; jsch jsch = 새로운 jsch (); 개인 세션 세션; 개인 채널 채널; 개인 채널 sftp SFTP; 공개 문자열 gethost () {return host; } public void sethost (문자열 호스트) {this.host = host; } public String getUser () {return user; } public void setUser (문자열 사용자) {this.user = user; } public ssh () {} public ssh (문자열 호스트, int 포트, 문자열 사용자, 문자열 암호) {this.host = host; this.user = 사용자; this.password = 비밀번호; this.port = 포트; } / ** * connect ssh * @throws jschexception * / public void connect () jschexception {if (session == null) {session = jsch.getsession (사용자, 호스트, 포트); myuserinfo ui = 새로운 myuserinfo (); SESSION.SETUSERINFO (UI); 세션 .setpassword (비밀번호); session.connect (); channel = session.openchannel (프로토콜); channel.connect (); sftp = (channelsftp) 채널; }} / ** * 분리 SSH * / public void Disternect () {if (session! = null) {session.disconnect (); 세션 = null; }} / ** * 업로드 * @param localfilename * @param remotefilename * / public boolean upload (string localfilename, String remotefilename) 예외 {boolean bsucc = false; try {sftpprogressmonitor monitor = new MyProgressMonitor (); int mode = channelsftp.overwrite; sftp.put (localFileName, implicefilename, monitor, mode); bsucc = true; } catch (예외 e) {logger.error (e); } 마침내 {if (null! = channel) {channel.disconnect (); }} return bsucc; } / ** * 파일 삭제 * @param directory * @param filename * @return * / public boolean detectefile (문자열 디렉토리, 문자열 filename) {boolean flag = false; try {sftp.cd (directory); sftp.rm (filename); flag = true; } catch (sftpexception e) {flag = false; logger.error (e); } 반환 플래그; } / ** * 삭제 디렉토리 삭제 * @param directory dir delete * @param 확실히 삭제 * @return * / public string deletedir (string directory, boolean sure) {String 명령 = "rm -rf" + directory; 문자열 result = execcommand (명령, true); 반환 결과; }/** * CompressName * @param 디렉토리 이름이라는 zip로 파일과 디렉토리의 서브 디어를 압축 할 컨텐츠 디렉토리를 압축 한 후 디렉토리에서 이름을 압축 할 컨텐츠 디렉토리 * @throws sftpexception * @usage ssh.compressdir ( "/home/tfxiaozi/webapp", "test.zip"); */public void compressDir (문자열 디렉토리, 문자열 compressName)은 sftpexception {strows 명령 = "cd" + directory + "/nzip -r" + compressName + "./" + compressName.SubString (0, compressName.lastIndexOf ( ")); execcommand (명령, true); } / ** * 다운로드 * @param localfilename * @param remotefilename * @return * / public boolean download (String localfilename, String remoteFilename) {boolean bsucc = false; 채널 채널 = null; try {sftpprogressmonitor monitor = new MyProgressMonitor (); sftp.get (RemoteFilename, localFilename, Monitor, ChannelSftp.overwrite); bsucc = true; } catch (예외 e) {logger.error (e); } 마침내 {if (null! = channel) {channel.disconnect (); }} return bsucc; } / ** * 실행 명령 * @param 명령 * @param flag * @return * / public String execcommand (String 명령, 부울 플래그) {채널 채널 = null; inputStream in = null; StringBuffer sb = new StringBuffer ( ""); try {channel = session.openchannel ( "exec"); System.out.println ( "명령 :" + 명령); ((ChannelExec) 채널) .setCommand ( "내보내기 term = ansi &&" + command); ((ChannelExec) 채널) .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 (새 문자열 (tmp, 0, i)); } if (channel.isclosed ()) {break; }}} in.close (); } catch (예외 e) {logger.error (e); } 마침내 {if (channer! = null) {channel.disconnect (); }} return sb.toString (); } / ** * cpu 정보 가져 오기 * @return * / public string [] getCpuInfo () {채널 채널 = null; inputStream in = null; StringBuffer sb = new StringBuffer ( ""); try {channel = session.openchannel ( "exec"); ((ChannelExec) 채널) .setCommand ( "내보내기 term = ansi && top -bn 1"); // ansi는 = channel.getInputStream (); ((ChannelExec) 채널) .SeterRstream (System.err); channel.connect (); 바이트 [] tmp = 새로운 바이트 [10240]; while (true) {while (in.available ()> 0) {int i = in.read (tmp, 0, 10240); if (i <0) {break; } sb.append (새 문자열 (tmp, 0, i)); } if (channel.isclosed ()) {break; }}} catch (예외 e) {logger.error (e); } 마침내 {if (channer! = null) {channel.disconnect (); }} 문자열 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"); } / ** * 하드 디스크 정보 가져 오기 * @return * / public String gethardDiskInfo () 던지기 예외 {채널 채널 = null; inputStream in = null; StringBuffer sb = new StringBuffer ( ""); try {channel = session.openchannel ( "exec"); ((ChannelExec) 채널) .SetCommand ( "DF -LH"); in = Channel.getInputStream (); ((ChannelExec) 채널) .SeterRstream (System.err); channel.connect (); 바이트 [] tmp = 새로운 바이트 [10240]; while (true) {while (in.available ()> 0) {int i = in.read (tmp, 0, 10240); if (i <0) {break; } sb.append (새 문자열 (tmp, 0, i)); } if (channel.isclosed ()) {break; }}} catch (예외 e) {throw new runtimeexception (e); } 마침내 {if (channer! = null) {channel.disconnect (); }} 문자열 buf = sb.toString (); 문자열 [] info = buf.split ( "/n"); if (info.length> 2) {// 첫 번째 줄 : 파일 시스템 크기 사용 사용 가능한 사용% tmp = ""; for (int i = 1; i <info.length; i ++) {tmp = info [i]; 문자열 [] tmparr = tmp.split ( "%"); if (tmparr [1] .trim (). Equals ( "/")) {부울 플래그 = 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] + "indred," + result [3] + "free"; 부서지다; } else {buf = ""; }}}} else {buf = ""; } return buf; } / ** * 무료 바이트 수 * @return * @throws Exception * / public double getfreedisk () throws exception {String HardDiskInfo = gethardDiskInfo (); if (harddiskinfo == null || harddiskinfo.equals ( "")) {logger.error ( "무료 하드 디스크 공간 실패 ......"); 반품 -1; } string [] diskinfo = harddiskinfo.replace ( "", "") .split ( ","); if (diskinfo == null || diskinfo.length == 0) {logger.error ( "무료 디스크 정보 실패 ......"); 반품 -1; } string free = diskinfo [2]; free = free.substring (0, free.indexof ( "free")); //system.out.println("Free Space : " + free); 문자열 단위 = free.substring (free.length () -1); //system.out.println("Unit : " + unit); 문자열 freespace = free.substring (0, free.length () -1); double freespacel = double.parsedouble (Freespace); //system.out.println("free spacel : " + freespacel); if (init.equals ( "k")) {return freespacel*1024; } else if (init.equals ( "m")) {return freespacel*1024*1024; } else if (init.equals ( "g")) {return freespacel*1024*1024*1024; } else if (init.equals ( "t")) {return freespacel*1024*1024*1024*1024; } else if (init.equals ( "p")) {return freespacel*1024*1024*1024*1024; } 반환 0; } / ** * 지정된 디렉토리에서 모든 하위 디렉터와 파일을 가져옵니다 * @param directory * @return * @throws 예외 * / @suppresswarnings ( "rawtypes") public list <string> listfiles (String Directory) 예외 {vector filelist = null; List <string> filenamelist = new ArrayList <string> (); filelist = sftp.ls (디렉토리); iterator it = filelist.iterator (); while (it.hasnext ()) {String filename = ((channelsftp.lsentry) it.next ()). getFilename (); if (filename.startswith ( ".") || filename.startswith ( "..")) {계속; } filenamelist.add (filename); } return filenamelist; } public boolean mkdir (문자열 경로) {부울 플래그 = false; try {sftp.mkdir (Path); flag = true; } catch (sftpexception e) {flag = false; } 반환 플래그; }}테스트하십시오
public static void main (string [] arg)은 예외 {ssh ssh = new ssh ( "10.10.10.83", 22, "test", "test"); {ssh.connect (); } catch (jschexception e) {e.printstacktrace (); }/*문자열 remotepath = "/home/tfxiaozi/" + "webapp/"; try {ssh.listfiles (remotepath); } catch (예외 e) {ssh.mkdir (remotepath); }*//*부울 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); }* / /*부울 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 (예외 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 (예외 e) {system.out.println (e.getMessage ()); }*//*문자열 path = "/home/tfxiaozi/webapp1/test.zip"; {list <string> list = ssh.listfiles (path); for (string s : list) {system.out.println (s); } system.out.println ( "OK"); } catch (예외 e) {System.out.println ( "추출 실패 ...."); }*//*string command = "rm -rf/home/tfxiaozi/webapp1/" + "잉크 및 세척 중국 연구"; 문자열 sss = ssh.execcommand (command, true); System.out.println (SSS);*//*String findcommand = "찾기/홈/tfxiaozi/webapp1/잉크 및 세탁 중국어 연구-이름 index.html '"; 문자열 결과 = ssh.execcommand (findCommand, true); System.out.println (결과);* / /*문자열 path = ""; ssh.listfiles (remotepath);*//* ssh.deletedir ( "/home/tfxiaozi/webapp1", true); *//// 다음은 WebApp1 디렉토리, webApp1/xxx //ssh.execcommand("Unzip /home/tfxiaozi/webapp1/test.zip -d/home/tfxiaozi/webapp1 ", true로 압축 해제됩니다. // 다음은/webapp1/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 "); /*부울 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와 같은 매개 변수를 추가해야합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.