如何使用Java SFTP Library JSch将文件从一个目录传输到另一个目录?

时间:2015-09-25 17:17:34

标签: java sftp jsch

我需要使用JSch库编写文件传输程序。我有一个带有两个文件夹的简单目录 -

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

我想做的是简单地将文件从我的机器中的一个目录传输到另一个目录。感谢任何提示,谢谢!

4 个答案:

答案 0 :(得分:10)

请注意,要在两个文件夹之间进行复制,不需要使用SFTP。可以从一个文件夹复制到另一个文件夹而不涉及SFTP协议,该协议主要用于远程复制文件,从本地计算机到远程计算机,或从远程计算机到(相同或不同)远程计算机,或从远程机器到本地机器。

这是因为FTP是基于网络的协议。因此,使用它(或任何相关协议)将使用网络(或模拟网络)。

JSch提供的安全性是旨在防止网络上发生的某些类型攻击的安全措施。它不会在机器内提供任何额外的安全性。

要在一台机器上的文件夹之间复制文件,最简单的方法是不要使用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方法。

答案 1 :(得分:2)

实际上JSch是为远程工作而设计的,而文件系统修改就是这类工作之一。 @Edwin Buck应答使用网络来处理远程主机上的本地文件夹。有更好的方法:

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

我手上没有窗户,因此我的样本是针对unix的。但这个想法很简单:在远程主机上执行copy命令。

答案 2 :(得分: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示例。一旦你有了它的工作,它就像一个魅力,所以它值得的麻烦。

答案 3 :(得分:0)

核心SFTP协议不支持复制远程文件。

copy-file extension to the protocol的草稿,但是只有少数SFTP服务器(例如ProFTPD/mod_sftp和Bitvise SFTP服务器)支持。

最广泛使用的OpenSSH SFTP服务器绝对不支持它。

JSch库也不支持它。


另请参阅我对How can I copy/duplicate a file to another directory using SFTP?的回答


因此,不幸的是,实际上在“ exec”通道(ChannelExec)上使用cp shell命令是最好的可用方法(假设您连接到* nix服务器并且您具有shell访问权限)。


如果您没有外壳访问权限,那么唯一的选择确实是将文件下载到本地临时文件夹,然后将其上传回新位置(或使用流,以避免使用临时文件)。这就是@Edwin Buck接受的答案。