English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Implementazione del trasferimento di file su server utilizzando ssh

Implementazione di upload e download dei file server tramite ssh

Parole iniziali

Prima avevo registrato un articolo su come implementare il metodo di upload e download dei file server utilizzando il componente open source FTP di Apache, ma ho scoperto più tardi che ci sono problemi di permessi durante l'eliminazione, che causano l'impossibilità di eliminare i file sul server. Anche se non ci sono problemi dopo aver configurato i permessi di lettura e scrittura con FileZilla Server su Windows, è ancora un po' difficile da usare sul lato server.

Poiché è necessario implementare la funzione di gestione delle risorse, oltre allo storage di FastDFS per file singoli, alcune risorse specifiche sono intenzionate per essere temporaneamente conservate sul server. I colleghi del team di progetto dicono che non apriranno un servizio FTP speciale sul server, quindi è stato modificato per utilizzare il metodo sftp per le operazioni.

Come si usa questa cosa?

Prima di tutto, devi scaricare il pacchetto jar jsch, l'indirizzo è: http://www.jcraft.com/jsch/. Il sito web è anche molto chiaro: JSch è un'implementazione pura in Java di SSH2. Questo è l'implementazione SSH2 in Java. Puoi usarlo normalmente utilizzando l'IP e il porto, inserendo il nome utente e la password. Allora come usare questo utile strumento?

Non c'è bisogno di saper scrivere, l'ufficio anche ha fornito esempi, collegamento:http://www.jcraft.com/jsch/examples/Shell.javaDiamo un'occhiata:

/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/**
 * Questo programma ti permette di connetterti al server sshd e ottenere la prompt del shell.
 * $ CLASSPATH=.:../build javac Shell.java 
 * $ CLASSPATH=.:../build java Shell
 * Ti verrà richiesto il nome utente, l'hostname e la password. 
 * Se tutto va bene, otterrai la prompt del shell. L'output potrebbe
 * Potrebbe sembrare brutto a causa della mancanza di emulazione del terminale, ma è possibile eseguire comandi.
 *
 */
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("Inserisci nomeutente@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("Inserisci password");
  session.setPassword(passwd);
  UserInfo ui = new MyUserInfo(){
  public void showMessage(String message){
   JOptionPane.showMessageDialog(null, message);
  {}
  public boolean promptYesNo(String message){
   Object[] options={ "sì", "no" };
   int foo=JOptionPane.showOptionDialog(null, 
            message,
            "Attenzione", 
            JOptionPane.DEFAULT_OPTION, 
            JOptionPane.WARNING_MESSAGE,
            null, options, options[0]);
   return foo==0;
  {}
  // Se la password non è fornita prima dell'invocazione di Session#connect(),
  // implementare anche i seguenti metodi,
  // * UserInfo#getPassword(),
  // * UserInfo#promptPassword(String message) e
  // * UIKeyboardInteractive#promptKeyboardInteractive()
  };
  session.setUserInfo(ui);
  // Non deve essere raccomandato, ma se si desidera saltare il controllo della chiave host,
  // invoca il seguente,
  // session.setConfig("StrictHostKeyChecking", "no");
  //session.connect();
  session.connect(30000); // stabilendo una connessione con timeout.
  Channel channel=session.openChannel("shell");
  // Abilita l'inoltro dell'agente.
  //((ChannelShell)channel).setAgentForwarding(true);
  channel.setInputStream(System.in);
  /*
  // un trucco per l'invocazione di MS-DOS su 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);
  /*
  // Scegli il tipo di pty "vt102".
  ((ChannelShell)channel).setPtyType("vt102");
  */
  /*
  // Imposta la variabile d'ambiente "LANG" come "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
       implementa 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; }
 
 
            
            
            String[] prompt,
            boolean[] echo){
  return null;
 {}
 {}
{}

In questo codice, possiamo基本上 vedere ciò di cui abbiamo bisogno. Prima di tutto, dobbiamo creare le informazioni utente, che sono principalmente utilizzate per l'autenticazione. Basta implementare gli interfacce UserInfo e UIKeyboardInteractive e poi impostare userInfo nella sessione creata attraverso la creazione della sessione, infine connettersi.

Impacchettamento del caricamento e del download dei file

Come sopra, ecco l'uso di base di Jsch, che è solo un po' di routine di base. Ora cerchiamo di impacchettare le funzionalità che vogliamo utilizzare, realizzando operazioni come il caricamento e il download dei file.

Prima di tutto, creiamo anche un 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;
  }
   logger.error(e);
  } finally {
   if (null != channel) {
    channel.disconnect();
   {}
  {}
  return bSucc;
 {}
 /**
  * elimina il file
  * @param directory
  * @param fileName
  * @return
  */
 public boolean deleteFile(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;
 {}
 /**
  * elimina la directory
  * @param directory la directory da eliminare
  * @param sure essere sicuri di eliminare
  * @return
  */
 public String deleteDir(String directory, boolean sure) {
  String command = "rm -rf " + directory;
  String result = execCommand(command, true);
  return result;
 {}
 /**
  * comprime i file e le sottodirectory della directory in un archivio chiamato compressName
  * @param directory la directory di contenuto da compressire
  * @param compressName il nome nella directory dopo la compressione
  * @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;
  }
   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");
 {}
 /**
  * ottieni informazioni sul disco fisso
  * @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] + " totale, " + result[2] + " utilizzati, " + result[3] + " liberi";
      break;
     }
      buf = "";
     {}
    {}
   {}
  }
   buf = "";
  {}
  return buf;
 {}
 /**
  * Restituisce il numero di byte liberi
  * @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:\
  String unit = free.substring(free.length()-1);
  //System.out.println("unit:\
  String freeSpace = free.substring(0, free.length()-1);
  double freeSpaceL = Double.parseDouble(freeSpace);
  //System.out.println("free spaceL:\
  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;
 {}
{}

Testa questo

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("estrazione fallita....");
  }*/
  /*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);
   */
  //Questa operazione decomprimerà nel percorso webapp1, webapp1/test/xxx
  //ssh.execCommand("unzip /home/tfxiaozi/webapp1/test.zip -d /home/tfxiaozi/webapp1", true);
  //Questa operazione decomprimerà nel percorso /webapp1/test, che è anche 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();
 {}

Questo è l'operazione diretta utilizzando il metodo Linux, ma è necessario notare che per i file in cinese, durante la decompressione, potrebbe esserci una disordine di codifica, è necessario aggiungere i parametri, come unzip -O cp936 test.zip -d /home/tfxiaozi/test.

Questo è tutto il contenuto dell'articolo, speriamo che sia utile per la tua apprendimento, e ti preghiamo di sostenere e urlare le lezioni.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta ai rispettivi autori, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume alcuna responsabilità legale. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare