web-dev-qa-db-fra.com

Comment transférer un fichier d'un répertoire à un autre à l'aide de Java SFTP Library JSch?

Je dois programmer un transfert de fichier à l'aide de la bibliothèque JSch. J'ai un répertoire simple avec deux dossiers - 

 enter image description here

Dans le dossier SFTP_1, j'ai une image bitmap. Et le dossier SFTP_2 est juste un dossier vide. Mon objectif est de transférer l'image à l'aide de SFTP de SFTP_1 à SFTP_2. 

Voici mon code jusqu'ici:

import com.jcraft.jsch.*;

import Java.awt.Desktop;

import Java.nio.channels.Channel;


public class FileTransfer {

    public FileTransfer() {  
        super();                               
    }

       public static void main (String[] args) {
        FileTransfer fileTransfer = new FileTransfer();              

    JSch jsch = new JSch();

          try {

              String Host = "127.0.0.1";
              int port = 22;

              String user = "user";
              Session session = jsch.getSession(user, Host, port);      
              session = jsch.getSession("username", "127.0.0.1", 22);
              session.connect();

             //Channel channel  = session.openChannel("sftp");
              ChannelSftp sftp = null;
              sftp = (ChannelSftp)session.openChannel("sftp") ; //channel;
              //channel.connect();
              //Channel channel = session.openChannel("Shell");  



             sftp.rename("C:\\Users\\ADMIN\\Desktop\\Work\\ConnectOne_Bancorp\\Java_Work\\SFTP_1\\house.bmp", "C:\\Users\\ADMIN\\Desktop\\Work\\ConnectOne_Bancorp\\Java_Work\\SFTP_2\\house.bmp");  //  /SFTP_1/file.txt 
              //sftpChannel.get("remotefile.txt", "localfile.txt");
              //sftpChannel.exit();
              session.disconnect();

          } catch (JSchException e) {
              e.printStackTrace();  
          } catch (SftpException e) {
              e.printStackTrace();
          }
       }
}

Ce que je voudrais faire, c'est simplement transférer un fichier d'un répertoire de ma machine vers un autre répertoire. des conseils appréciés, merci!

15
Coffee

Notez que pour copier entre deux dossiers, il n’est pas nécessaire d’utiliser SFTP. Il est possible de copier d’un dossier à un autre sans faire appel au protocole SFTP, qui est principalement utilisé pour copier des fichiers à distance, soit de la machine locale à une machine distante, soit d’une machine distante à une machine distante identique ou différente, ou de la machine distante. la machine distante à la machine locale.

C'est parce que le FTP est un protocole basé sur le réseau. Donc, son utilisation (ou l'un de ses protocoles associés) va utiliser le réseau (ou un réseau simulé).

La sécurité fournie par JSch est une sécurité conçue pour protéger contre certains types d'attaques survenant sur les réseaux. Cela n'apportera aucune sécurité supplémentaire à la machine.

Pour copier des fichiers entre des dossiers sur un seul ordinateur, le moyen le plus simple de le faire est de ne pas utiliser JSch,

private static void copyFileUsingJava7Files(File source, File dest)
        throws IOException {
    Files.copy(source.toPath(), dest.toPath());
}

Il existe d'autres techniques, et si vous voulez vraiment utiliser JSch, vous devez comprendre que beaucoup d'informations "supplémentaires" doivent être fournies à JSch pour pouvoir se connecter à la machine sur laquelle vous êtes, car il essaiera de se connecter à cette machine comme si il se connectait à travers le réseau

Session sessionRead = jsch.getSession("username", "127.0.0.1", 22);
sessionRead.connect();

Session sessionWrite = jsch.getSession("username", "127.0.0.1", 22);
sessionWrite.connect();

ChannelSftp channelRead = (ChannelSftp)sessionRead.openChannel("sftp");
channelRead.connect();

ChannelSftp channelWrite = (ChannelSftp)sessionWrite.openChannel("sftp");
channelWrite.connect();

PipedInputStream pin = new PipedInputStream(2048);
PipedOutputStream pout = new PipedOutputStream(pin);

channelRead.get("/path/to/your/file/including/filename.txt", pout);
channelWrite.put(pin, "/path/to/your/file/destination/including/filename.txt");

channelRead.disconnect();
channelWrite.disconnect();

sessionRead.disconnect();
sessionWrite.disconnect();

Le code ci-dessus manque de vérification d'erreur, de gestion des exceptions et de routines de secours pour les fichiers manquants, les réseaux en panne, etc. Mais vous devriez en avoir l'idée principale.

Il devrait également être évident que l’utilisation d’un protocole de réseau où aucun protocole de réseau ne doit exister ouvre la porte à beaucoup plus de scénarios de défaillance. Utilisez la méthode SFTP uniquement si votre programme est bientôt conçu pour copier des fichiers qui ne se trouvent pas tous les deux sur votre ordinateur.

10
Edwin Buck

Si l’affiche originale recherche réellement un exemple de travail de JSch entre deux sites FTP distincts, voici ce qui suit:

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
...
JSch jsch = new JSch();
JSch session = null;
try {
  session = jsch.getSession(userid, sourceservername, sourceserverport);
  session.setPassword(sourceserverpassword);
  Properties props = new Properties();
  props.put("StrictHostKeyChecking", "no");
  session.setConfig(props);
  session.connect();
  Channel channel = session.openChannel("sftp");
  channel.connect();
  ChanelSftp channelsftp = (ChannelSftp) channel;
  channelsftp.cd(sourcefilepath);
  channelsftp.lcd(localfilepath);
  FileOutputStream fos = new FileOutputStream(new File(localfilepath + "/" + localfilename));
  channelsftp.get(sourcefilename, fos);
  fos.flush();
  fos.close();
  channelsftp.disconnect()
  session.disconnect();
} catch (Exception e) {
  e.printStackTrace();
}

En pratique, vous pouvez diviser ces actions en instructions try {} catch () {} bloquées afin d'introduire un rapport d'erreur plus granulaire, ainsi que d'ajouter des lignes de sortie informatives pour informer l'utilisateur du statut, etc. vous y rendre. Certes, bien que les exemples JSch soient meilleurs que la plupart des exemples de librairies de gratuiciels, même les bons comme celui-ci, il peut y avoir des omissions parmi eux concernant les détails qui peuvent faire échouer votre tentative de faire fonctionner les choses. J'espère que cela aidera si pas l'affiche originale, alors quelqu'un d'autre à la recherche d'un exemple de travail JSch. Une fois que ça fonctionne, ça va comme un charme, alors ça vaut le coup.

2
Matt Campbell

En réalité, JSch est conçu pour le travail à distance, et la modification du système de fichiers est du type de ce type de travail. @ Edwin Buck answer utilise le réseau pour gérer les dossiers locaux de l'hôte distant. Il y a une meilleure approche:

session.connect();
ChannelExec exec = (ChannelExec) session.openChannel("exec");
exec.setCommand("cp a.out b.out");
exec.connect();

Je n'ai pas de fenêtre sur la main, mon échantillon est donc destiné à Unix. Mais l’idée est simple: exécuter une commande de copie sur l’hôte distant.

2
sibnick

Un protocole SFTP principal ne prend pas en charge la duplication de fichiers distants.

Il existe un brouillon d'extension copy-file au protocole , mais qui n'est pris en charge que par quelques serveurs SFTP ( ProFTPD/mod_sftp et le serveur Bitvise SFTP par exemple).

Il n’est certainement pas pris en charge par le serveur OpenSSH SFTP le plus répandu. 

Et ce n'est pas non plus supporté par la bibliothèque JSch.


Voir aussi ma réponse à Comment copier/dupliquer un fichier dans un autre répertoire en utilisant SFTP?


Donc, utiliser la commande cp Shell sur un canal "exec" ( ChannelExec ) est malheureusement la meilleure approche disponible (en supposant que vous vous connectiez à un serveur * nix et que vous ayez un accès Shell).


Si vous ne disposez pas d'un accès Shell, votre seule option est en effet de télécharger le fichier dans un dossier temporaire local et de le réimporter au nouvel emplacement (ou d'utiliser des flux pour éviter un fichier temporaire). C'est ce que montre la réponse acceptée par @Edwin Buck.

0
Martin Prikryl