O upload e download de arquivos do servidor através do SSH
Palavras escritas na frente
Eu já gravei um método para fazer upload e baixar arquivos do servidor usando o componente de código aberto FTP do Apache, mas depois descobri que haverá alguns problemas de permissão ao excluir, o que levará à incapacidade de excluir arquivos no servidor. Embora não haja problema depois de definir permissões de leitura e gravação usando o FileZilla Server no Windows, ainda é um pouco difícil de usar no lado do servidor.
Como eu preciso implementar funções de gerenciamento de recursos, além do armazenamento FastDFS de arquivos únicos, ainda está planejado algum armazenamento de recursos específicos para ser armazenado temporariamente no servidor. Os colegas da equipe do projeto disseram que não abririam serviços de FTP especificamente no servidor posteriormente, então eles mudaram para o modo SFTP para operar.
Como usar essa coisa
Primeiro, você precisa baixar o pacote JSCH JAR, o endereço é: http://www.jcraft.com/jsch/. O site também escreve muito claramente: o JSCH é uma implementação pura de Java do SSH2. Esta é uma implementação pura de Java do SSH2. Use IP e Porta, digite o nome de usuário e a senha e você pode usá -lo normalmente, o que é o mesmo que o método de uso do CRT seguro. Então, como você usa essa ferramenta útil?
Na verdade, não importa se você não pode escrever. O funcionário também deu um exemplo. O link é: http://www.jcraft.com/jsch/examples/shell.java. Vamos dar uma olhada:
/* -* -modo: java; Offset C-Basic: 2; Modo de indent-tabs: nil-*-*// ***Este programa permite que você se conecte ao servidor SSHD e obtenha o prompt do shell. * $ ClassPath =.: ../ Construa javac shell.java * $ ClassPath = .: ../ Construa Java Shell * Você será solicitado a nome de usuário, nome do host e passwd. * Se tudo funcionar bem, você receberá o prompt do shell. A saída pode * ser feia por falta de emissão de terminais, mas você pode emitir comandos. **/importar com.jcraft.jsch.*; importar java.awt. //jsch.setknownhosts("/home/foo/.ssh/known_hosts "); String host = null; if (arg.length> 0) {host = arg [0]; } else {host = JoptionPane.showInputDialog ("Digite UserName@HostName", System.getProperty ("user.name")+ "@locAlHost"); } String user = host.substring (0, host.indexof ('@')); host = host.substring (host.indexof ('@')+1); Sessão sessão = jsch.getSession (usuário, host, 22); String passwd = joptionpane.showInputDialog ("digite a senha"); session.setPassword (passwd); UserInfo ui = new Myuserinfo () {public void showMessage (string message) {joptionPane.showMessagedialog (null, mensagem); } public boolean Promptyesno (string message) {object [] options = {"sim", "não"}; int foo = joptionpane.showOptionDialog (null, mensagem, "aviso", joptionpane.default_option, joptionpane.warning_message, nulo, opções, opções [0]); retornar foo == 0; } // Se a senha não for fornecida antes da invocação da sessão#Connect (), // Implementar também os seguintes métodos, // * userInfo#getPassword (), // * userinfo#PromptPassword (string message) e // * uikeyboardinteractive#PromptActionInteractive ()}; session.setUserinfo (UI); // Não deve ser recomendado, mas se você quiser pular a verificação da chave host, // Invoque a seguir, // session.setConfig ("StricThostKeyChecking", "não"); //Session.Connect (); session.Connect (30000); // Fazendo uma conexão com o tempo limite. Canal canal = session.openchannel ("shell"); // Habilitar agente-forwarding. //(Channelshell)Channel).SetAgentForwarding(True); canal.setInputStream (System.in); /* // Um hack para prompt MS-DOS no Windows. canal.setInputStream (novo filtroinputStream (System.in) {public int read (byte [] b, int off, int len) lança ioexception {return in.read (b, off, (len> 1024? 1024: len));}}); */ canal.setOutputStream (System.out); /* // Escolha o Pty-Type "VT102". ((Canal) canal) .SetPtyType ("VT102"); * / /* // Defina a variável de ambiente "Lang" como "ja_jp.eucjp". ((Canal) canal) .setenv ("lang", "ja_jp.eucjp"); *///channel.connect (); canal.Connect (3*1000); } catch (Exceção e) {System.out.println (e); }} Classe abstrata estática pública myuserinfo implementa UserInfo, uikeyboardinteractive {public string getPassword () {return null; } public boolean Promptyesno (string str) {return false; } public string getPassPhrase () {return null; } public boolean Promptpasshrase (mensagem de string) {return false; } public boolean Promptpassword (string message) {return false; } public void showMessage (string message) {} public String [] PromptKeyBoardinterActive (destino da string, nome da string, instrução da string, string [] prompt, boolean [] echo) {return null; }}}Neste código, podemos basicamente ver o que precisamos. Primeiro, precisamos criar informações do usuário. Isso é usado principalmente para autenticação. Basta implementar as duas interfaces do UserInfo e UikeyboardInteractive. Em seguida, criando uma sessão, defina o userInfo e, finalmente, conecte -se.
Upload e download de arquivo encapsulado
O acima é o método básico de uso do JSCH, ou seja, algumas rotinas básicas. Vamos encapsular as funções que queremos usar, implementar uma série de operações, como o upload e o download de arquivos.
Primeiro, crie um usuárioInfo:
classe pública myuserinfo implementa o userInfo, uikeyboardinteractive {public string getPassword () {return null; } public boolean Promptyesno (string str) {return true; } public string getPassPhrase () {return null; } public boolean PromptPasshrase (mensagem de string) {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; }}Aqui está a classe de implementação:
pacote com.tfxiaozi.common.utils; importar java.io.inputStream; importar java.util.ArrayList; importar java.util.iterator; importar java.util.list; import java.util.vector; import.apache.ang4j.logger; com.jcraft.jsch.channelexec; import com.jcraft.jsch.channelsftp; import com.jcraft.jsch.jsch; import com.jcraft.jsch.jschException; importPermOnChTh.jcraft.jsch.session; import com.jcraft.jsch.sftSoMOPTIMIL; * @author tfxiaozi * */public class ssh {logger logger = logger.getLogger (this.getClass ()); Private String host = ""; String private String user = ""; private int porta = 22; private string senha = ""; Protocolo de sequência final estática privada = "sftp"; JSCH JSCH = new JSCH (); sessão privada sessão; canal de canal privado; canais privados 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, porta int, string user, string senha) {this.host = host; this.User = usuário; this.password = senha; this.port = porta; } / ** * Connect ssh * @throws jschException * / public void connect () lança jschException {if (session == null) {session = jsch.getSession (usuário, host, porta); Myuserinfo ui = new Myuserinfo (); session.setUserinfo (UI); session.setPassword (senha); session.Connect (); canal = session.OPENCHANNEL (protocolo); canal.Connect (); canal sftp = (canallftp); }} / ** * desconecte ssh * / public void desconect () {if (session! = null) {session.disconnect (); sessão = nulo; }} / ** * upload * @param localFilename * @param remotefilename * @return * / public boolean upload (string localfilename, string remotefileName) lança exceção {boolean bsucc = false; tente {sftprogressmonitor monitor = new MyProgressMonitor (); Int Mode = canaisftp.OverWrite; sftp.put (LocalFilename, RemoteFileName, Monitor, Mode); bsucc = true; } catch (Exceção e) {Logger.error (e); } finalmente {if (null! = canal) {canal.disconnect (); }} retornar bsucc; } / ** * Excluir arquivo * @Param Directory * @param FileName * @return * / public boolean DetectEfile (diretório da string, string filename) {boolean sinalizador = false; tente {sftp.cd (diretório); sftp.rm (nome do arquivo); bandeira = true; } catch (sftPexception e) {flag = false; Logger.error (e); } retornar sinalizador; } / ** * Excluir diretório * @param diretório diretório para ser excluído * @param Certamente certifique -se de excluir * @return * / public string deletedir (diretório da string, boolean stear) {string command = "rm -rf" + diretório; String resultado = ExecCommand (comando, true); resultado de retorno; }/** * Compressa os arquivos e o sub-diretório em um zip chamado CompressName * @Param Directory O diretório de conteúdo é compactar * @param compressname o nome no diretório depois que ele é compactado * @THROWSPAPPAPPPECCECCECCETION * @USAGE SSH.comPressdir ("/home/tfxiaozi/webAppApp" ". */public void compressdir (diretório de string, string compactName) lança sftpexception {string command = "cd" + diretório + "/nzip -r" + compressname + "./" + compressname.substring (0, compressname.lastIndexof ("."); EXecCommand (comando, true); } / ** * Download * @param LocalFilename * @param remotefilename * @return * / public boolean Download (string localfileName, string remotefilename) {boolean bsucc = false; Canal canal = nulo; tente {sftprogressmonitor monitor = new MyProgressMonitor (); sftp.get (RemoteFilename, LocalFileName, Monitor, canaisftp.overwrite); bsucc = true; } catch (Exceção e) {Logger.error (e); } finalmente {if (null! = canal) {canal.disconnect (); }} retornar bsucc; } / ** * Execute comando * @param comando * @param sinalizador * @return * / public string ExecCommand (comando string, sinalizador booleano) {canal canal = null; InputStream in = null; StringBuffer sb = new StringBuffer (""); tente {canal = session.openchannel ("Exec"); System.out.println ("comando:" + comando); ((ChannelExec) canal) .SetCommand ("Exportar termo = Ansi &&" + comando); ((ChannelExec) canal) .SterRStream (System.err); in = canal.getInputStream (); canal.Connect (); if (flag) {byte [] tmp = novo 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 (canal.isclosed ()) {break; }}} in.close (); } catch (Exceção e) {Logger.error (e); } finalmente {if (canal! = null) {canal.disconnect (); }} return sb.toString (); } / ** * Obtenha informações da CPU * @return * / public String [] getCpuinfo () {canal canal = null; InputStream in = null; StringBuffer sb = new StringBuffer (""); tente {canal = session.openchannel ("Exec"); (((Canalxex) canal) .setCommand ("Exportar termo = Ansi && top -bn 1"); // ANSI deve adicionar = canal.getInputStream (); ((ChannelExec) canal) .SterRStream (System.err); canal.Connect (); byte [] tmp = novo 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 (canal.isclosed ()) {break; }}} catch (Exceção e) {Logger.error (e); } finalmente {if (canal! = null) {canal.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 ("", ""); retornar buf.split ("// n"); } / ** * Obtenha informações de disco rígido * @return * / public string gethardDiskinfo () lança exceção {canal canal = null; InputStream in = null; StringBuffer sb = new StringBuffer (""); tente {canal = session.openchannel ("Exec"); ((ChannelExec) canal) .SetCommand ("df -lh"); in = canal.getInputStream (); ((ChannelExec) canal) .SterRStream (System.err); canal.Connect (); byte [] tmp = novo 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 (canal.isclosed ()) {break; }}} Catch (Exceção e) {lança nova RunTimeException (e); } finalmente {if (canal! = null) {canal.disconnect (); }} String buf = sb.toString (); String [] info = buf.split ("/n"); if (info.length> 2) {// Primeira linha: tamanho do sistema de arquivos usado use% use% montado na string tmp = ""; for (int i = 1; i <info.length; i ++) {tmp = info [i]; String [] tmparr = tmp.split ("%"); if (tmparr [1] .Trim (). Equals ("/")) {bandeira booleana = true; while (flag) {tmp = tmp.replaceall ("", ""); if (tmp.indexof ("") == -1) {flag = false; }} String [] resultado = tmp.split (""); if (resultado! = null && result.Length == 6) {buf = resultado [1] + "total" + resultado [2] + "usado" + resultado [3] + "livre"; quebrar; } else {buf = ""; }}}} else {buf = ""; } retornar buf; } / ** * Retorne o número de bytes gratuitos * @return * @throws Exception * / public duplo getfreedisk () lança exceção {string harddiskInfo = gethardDiskInfo (); if (harddiskInfo == null || harddiskinfo.equals ("" ")) {logger.error (" Obtenha o espaço de disco rígido gratuito falhou ...... "); retornar -1; } String [] diskinfo = harddiskinfo.replace ("", "") .split (","); if (diskinfo == null || diskinfo.length == 0) {Logger.error ("Obtenha falhas nas informações do disco livre ......"); retornar -1; } String free = diskinfo [2]; free = free.substring (0, free.indexof ("free")); //System.out.println("free space: " + grátis); Unidade de string = free.substring (free.length ()-1); //System.out.println("Unit: " + unidade); String freespace = free.substring (0, free.length ()-1); duplo freespacel = duplo.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; } retornar 0; } / ** * Obtenha todos os subdiretos e arquivos no diretório especificado * @Param Directory * @return * @throws Exception * / @suppresswarnings ("RawTypes") list <tring> listfiles (diretório de string) lança a exceção {vector FileList = null; List <String> filenamelist = new ArrayList <String> (); fileList = sftp.ls (diretório); Iterator it = filelist.iterator (); while (it.hasNext ()) {string filename = ((canaisftp.lSentry) it.Next ()). getFileName (); if (FILENAME.STARTSWITH (".") || FILENAME.STARTSWITH ("..")) {continuação; } filenamelist.add (nome do arquivo); } retornar filenamelist; } public boolean mkdir (caminho da string) {bandeira booleana = false; tente {sftp.mkdir (caminho); bandeira = true; } catch (sftPexception e) {flag = false; } retornar sinalizador; }}Teste
public static void main (string [] arg) lança exceção {ssh ssh = new ssh ("10.10.10.83", 22, "teste", "teste"); tente {ssh.connect (); } catch (jschException e) {e.printStackTrace (); }/*String remotepath = "/home/tfxiaozi/" + "webApp/"; tente {ssh.listfiles (remotepath); } catch (Exceção 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 (). Substituir ("", "")); //System.out.println (ssh.getfreedisk ()); /*List <String> list = ssh.listfiles ("webApp/teste"); para (string s: list) {System.out.println (s); }* / /*boolean b = ssh.detelefile ("webApp", "test.zip"); System.out.println (b);*//*tente {string s = ssh.execCommand ("ls -l/home/tfxiaozi/webApp1/teste", true); System.out.println (s); } catch (Exceção e) {System.out.println (e.getMessage ()); }*///ssh.sftp.setFilenameEncoding("utf-8 "); /*tente {string ss = ssh.execCommand ("unzip /home/tfxiaozi/webapp1/test.zip -d/home/tfxiaozi/webApp1/", true); System.out.println (SS); } catch (Exceção e) {System.out.println (e.getMessage ()); }*//*String path = "/home/tfxiaozi/webapp1/test.zip"; tente {list <string> list = ssh.listfiles (path); para (string s: list) {System.out.println (s); } System.out.println ("ok"); } catch (Exceção e) {System.out.println ("Extrato falhou ...."); }*//*String command = "rm -rf/home/tfxiaozi/webApp1/" + "tinta e lavagem de estudos chineses"; String sss = ssh.execCommand (comando, true); System.out.println (SSS);*//*string findCommand = "find/home/tfxiaozi/webApp1/tinta e lavagem de estudos chineses-nomes 'index.html'"; Resultado string = ssh.execCommand (findCommand, true); System.out.println (resultado);* / /*string path = ""; ssh.listfiles (remotepath);*//* ssh.deleletedir ("/home/tfxiaozi/webApp1", true); */// O seguinte será descomprimido para o diretório webApp1, webApp1/test/xxx //ssh.execcommand("unzip /home/tfxiaozi/webapp1/test.zip -d/home/tfxiaozi/webApp1 ", verdadeiro); // O seguinte será descompactado para o/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 (); } O exposto acima é usar o Linux para operar diretamente, mas deve -se notar que, para arquivos chineses, quando descomprimindo, pode haver código ilegal ao passar, e os parâmetros precisam ser adicionados, como o UNZIP -O CP936 Test.zip -d/home/tfxiaozi/teste.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.