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

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

Upload et téléchargement de fichiers serveurs via SSH

Préambule

J'avais déjà enregistré une méthode pour la mise en œuvre de l'upload et le téléchargement de fichiers serveurs en utilisant le composant open source FTP d'Apache, mais j'ai découvert plus tard qu'il y avait des problèmes de permissions lors de la suppression, ce qui rendait impossible la suppression de fichiers sur le serveur. Bien que cela fonctionne après avoir configuré les permissions de lecture/écriture avec FileZilla Server sur Windows, il reste encore des problèmes à résoudre sur le serveur.

Parce que je dois implémenter la fonction de gestion des ressources, en plus du stockage de fichiers uniques FastDFS, certains types de ressources spécifiques sont encore prévus pour être temporairement stockés sur le serveur, les collègues du projet ont dit qu'il n'y aura pas de service FTP spécifique sur le serveur, donc j'ai changé en mode sftp pour l'opération.

Ce que l'on doit utiliser

Tout d'abord, vous devez télécharger le paquet jar jsch, l'adresse est : http://www.jcraft.com/jsch/。网站上也很清楚地写着:JSch est une implémentation en pur Java de SSH2. C'est SSH2cette implémentation en pur Java. Utilisez l'IP et le port, entrez le nom d'utilisateur et le mot de passe pour une utilisation normale, de la même manière que Secure CRT. Alors, comment utiliser cet outil utile ?

En réalité, il n'est pas nécessaire d'écrire, car l'éditeur officiel a également fourni des exemples, lien :http://www.jcraft.com/jsch/exemples/Shell.java,来看看吧:

/* -*-mode:java; c-de base-décalage:2; indentation-onglets-mode:nil -*- */
/**
 * Ce programme vous permet de vous connecter au serveur sshd et d'obtenir l'invite de shell.
 * $ CLASSPATH=.:../construire javac Shell.java 
 * $ CLASSPATH=.:../construire java Shell
 * Vous serez invité à saisir le nom d'utilisateur, le nom d'hôte et le mot de passe. 
 * Si tout fonctionne correctement, vous obtiendrez l'invite de shell. Les sorties peuvent
 * avoir l'air laid en raison du manque de terminal-émulation, mais vous pouvez exécuter des commandes.
 *
 */
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;
  si(arg.length>0){
  host=arg[0];
  }
  sinon{
  host=JOptionPane.showInputDialog("Entrez le nom d'utilisateur@nom_d'hôte",
           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("Entrez le mot de passe");
  session.setPassword(passwd);
  UserInfo ui = new MyUserInfo(){
  public void showMessage(String message){
   JOptionPane.showMessageDialog(null, message);
  }
  public boolean promptYesNo(String message){
   Object[] options={ "oui", "non" };
   int foo=JOptionPane.showOptionDialog(null, 
            message,
            "Attention", 
            JOptionPane.DEFAULT_OPTION, 
            JOptionPane.WARNING_MESSAGE,
            null, options, options[0]);
   retourner foo==0;
  }
  // Si le mot de passe n'est pas fourni avant l'appel de Session#connect(),
  // implémenter également les méthodes suivantes,
  // * UserInfo#getPassword(),
  // * UserInfo#promptPassword(String message) et
  // * 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; }
 
 
            
            
            String[] prompt,
            boolean[] echo){
  return null;
 }
 }
}

Dans ce code, nous pouvons voir ce dont nous avons besoin. Tout d'abord, nous devons créer des informations utilisateur, qui sont principalement utilisées pour l'authentification. Il suffit de réaliser les interfaces UserInfo et UIKeyboardInteractive, puis de créer une session de session et d'ajouter userInfo, enfin de se connecter.

Encapsulation du téléchargement et du téléversement de fichiers

Voici les méthodes d'utilisation de base de Jsch, qui sont essentiellement des schémas de base. Ensuite, nous allons encapsuler nous-mêmes les fonctionnalités que nous devons utiliser, telles que le téléchargement et le téléversement de fichiers, et d'autres opérations.

Tout d'abord, créons également 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;
 }
}

La classe implémentée suit :

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;
 }
 /**
  * connecter 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;
  }
 }
 /**
  * déconnecter 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{
  SftpProgressMonitor monitor = new MyProgressMonitor();
  try {
   SftpProgressMonitor monitor = new MyProgressMonitor();
   int mode = ChannelSftp.OVERWRITE;
   sftp.put(localFileName, remoteFileName, monitor, mode); 
   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 directory, 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) {
  SftpProgressMonitor monitor = new MyProgressMonitor();
  Channel channel = null;
  try {
   sftp.get(remoteFileName, localFileName, monitor, ChannelSftp.OVERWRITE);
   bSucc = true; 
   catch(Exception e) {
  }
   logger.error(e);
  } finally {
   if (null != channel) {
    channel.disconnect();
   }
  }
  return bSucc;
 }
 /**
  * exécuter la commande
  * @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 doit être ajouté
   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 = 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]; + " total, " + result[2]; + " utilisé, " + result[3]; + " free";
      break;
     } else {
      buf = "";
     }
    }
   }
  } else {
   buf = "";
  }
  return buf;
 }
 /**
  * retourner le nombre d'octets libres
  * @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;
 }
 /**
  * Obtenir tous les sous-répertoires et fichiers du répertoire spécifié
  * @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;
 }
}

Testez

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("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);
   */
  //Ce qui suit sera décompressé dans webapp1Le répertoire, webapp1/test/xxx
  //ssh.execCommand("unzip /home/tfxiaozi/webapp1/test.zip -d /home/tfxiaozi/webapp1", true);
  //Ce qui suit sera décompressé dans/webapp1/Le répertoire test, c'est aussi webapp1/test/test/xxx
  //ssh.execCommand("unzip /home/tfxiaozi/webapp1/test.zip -d /home/tfxiaozi/webapp1", true);
  //ssh.compressDir("/home/tfxiaozi/webapp1
  //ssh.sftp.cd("/home/tfxiaozi/webapp1");
  //ssh.compressDir("/home/tfxiaozi/webapp1
  /*boolean b = ssh.download("d:/temp/test.zip", "webapp/test.zip");
  System.out.println(b);*/
  //ssh.getHardDiskInfo();
  System.out.println(ssh.getFreeDisk());
  ssh.disconnect();
 }

C'est ainsi que vous pouvez opérer directement en utilisant le mode Linux, mais il est important de noter que pour les fichiers chinois, lors de l'extraction, il peut y avoir des caractères codés incorrectement, vous devez ajouter des paramètres, comme unzip -O cp936 test.zip -d /home/tfxiaozi/test。

C'est tout le contenu de cet article, j'espère qu'il vous aidera dans vos études, et j'espère que vous soutiendrez également le tutoriel criant.

Déclaration : le contenu de cet article est issu du réseau, propriété de ses auteurs respectifs, apporté par les utilisateurs d'Internet de manière volontaire et téléversé, ce site n'en possède pas la propriété, n'a pas été édité par l'homme, ni n'assume la responsabilité des responsabilités juridiques pertinentes. Si vous trouvez du contenu suspect de violation de droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)