web-dev-qa-db-ja.com

Java SFTP Library JSchを使用して、あるディレクトリから別のディレクトリにファイルを転送するにはどうすればよいですか?

JSchライブラリを使用してファイル転送をプログラムする必要があります。私は2つのフォルダを持つ単純なディレクトリを持っています-

enter image description here

の中に SFTP_1フォルダ、ビットマップ画像があります。そしてその SFTP_2フォルダは空のフォルダです。私の目標は、SFTPを使用してSFTP_1からSFTP_2にイメージを転送することです。

これまでのところ私のコードです:

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();
          }
       }
}

私がしたいことは、私のマシンのあるディレクトリから別のディレクトリにファイルを転送することです。感謝の気持ち、ありがとう!

15
Coffee

2つのフォルダ間でコピーする場合、SFTPを使用する必要がないことに注意してください。ローカルマシンからリモートマシンへ、またはリモートマシンから(同じまたは異なる)リモートマシンへ、またはリモートマシンからリモートでファイルをコピーするために主に使用されるSFTPプロトコルを使用せずに、1つのフォルダーから別のフォルダーにコピーできます。リモートマシンからローカルマシンへ。

これは、FTPがネットワークベースのプロトコルであるためです。したがって、それ(またはその関連プロトコルのいずれか)を使用すると、ネットワーク(またはシミュレートされたネットワーク)が使用されます。

JSchが提供するセキュリティは、ネットワークで発生する特定の種類の攻撃から保護するように設計されたセキュリティです。マシン内の追加のセキュリティは提供されません。

1台のマシンのフォルダ間でファイルをコピーするための最も簡単な方法は、JSchを使用しないことです。

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

他の手法もあり、JSchを本当に使用したい場合は、JSchが現在のマシンに接続するために多くの「追加」情報を提供する必要があることを認識する必要があります。ネットワークを介して接続していた

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();

上記のコードには、エラーチェック、例外処理、およびファイルが見つからない場合やネットワークが稼働していない場合のフォールバックルーチンがありません。

ネットワークプロトコルを使用する必要がないネットワークプロトコルを使用すると、さらに多くの障害シナリオへの扉が開かれることも明らかです。プログラムがまもなく両方のマシン上にないファイルをコピーするようになっている場合にのみ、SFTPメソッドを使用してください。

10
Edwin Buck

元の投稿者が2つの異なるFTPサイト間で動作するJSchの実際の例を実際に探している場合は、次のようになります。

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();
}

実際には、これらのアクションを個別のtry {} catch(){}ブロックステートメントに分割して、より詳細なエラーレポートを導入したり、ステータスなどをユーザーに通知するための情報出力行を追加したりできます。ただし、これはそこに着きます。確かに、JSchの例はフリーウェアライブラリのほとんどの例よりも優れていますが、このような優れた例であっても、細かい部分が欠落しているために、うまく機能しない場合があります。これが元のポスターではなくても役立つJSchの例を探している誰かに役立つことを願っています。一度動作させると、魅力的になるので、問題はありません。

2
Matt Campbell

実際、JSchはリモート作業用に設計されており、ファイルシステムの変更はそのような作業の1つです。 @Edwin Buckの回答では、ネットワークを使用して、リモートホスト上のローカルフォルダー間で対処しています。より良いアプローチがあります:

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

私の手には窓がないので、私のサンプルはUNIX用です。しかし、考え方は簡単です。リモートホストでコピーコマンドを実行します。

2
sibnick

コアSFTPプロトコルは、リモートファイルの複製をサポートしていません。

copy-fileプロトコルへの拡張 、しかし、それは少数のSFTPサーバー( ProFTPD/mod_sftp およびBitvise SFTPサーバーなど)でのみサポートされています。

最も広く普及しているOpenSSH SFTPサーバーではサポートされていません。

また、JSchライブラリでもサポートされていません。


私の回答も参照してください SFTPを使用してファイルを別のディレクトリにコピー/複製するにはどうすればよいですか?


したがって、実際にcpシェルコマンドを「exec」チャネル経由で使用する( ChannelExec )は、残念ながら最良の方法です(* nixサーバーに接続していて、シェルアクセスがあります)。


シェルアクセスがない場合は、ファイルをローカルの一時フォルダーにダウンロードして新しい場所にアップロードする(または、一時ファイルを避けるためにストリームを使用する)のが唯一のオプションです。これは、@ Edwin Buckが認めた回答が示すものです。

0
Martin Prikryl