如何使用JavaSFTP库JSch将文件从一个目录传输到另一个目录?

如何使用JavaSFTP库JSch将文件从一个目录传输到另一个目录?,java,sftp,jsch,Java,Sftp,Jsch,我需要使用JSch库编程文件传输。我有一个包含两个文件夹的简单目录- 在SFTP_1文件夹中,我有一个位图图像。而SFTP_2文件夹只是一个空文件夹。我的目标是使用SFTP将图像从SFTP_1传输到SFTP_2 以下是我迄今为止的代码: FileTransfer fileTransfer = new FileTransfer(); JSch jsch = new JSch(); String host = "127.0.0.1";

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

SFTP_1
文件夹中,我有一个位图图像。而
SFTP_2
文件夹只是一个空文件夹。我的目标是使用SFTP将图像从SFTP_1传输到SFTP_2

以下是我迄今为止的代码:

FileTransfer fileTransfer = new FileTransfer();              
      
JSch jsch = new JSch();

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

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

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");
session.disconnect();

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

请注意,要在两个文件夹之间复制,不需要使用SFTP。可以从一个文件夹复制到另一个文件夹,而不涉及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方法。

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

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

我手头没有windows,因此我的示例是针对unix的。但是想法很简单:在远程主机上执行copy命令。

如果原始海报实际上是在两个不同的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示例。一旦你让它工作起来,它确实像一个符咒,所以它值得麻烦。

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

有一个的草案,但只有少数SFTP服务器(例如Bitvise SFTP服务器)支持

最广泛使用的OpenSSH SFTP服务器肯定不支持它

JSch库也不支持它


另见我对这一问题的答复


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



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

谢谢!!最后一行是
channelWrite.put(
-它将有我们要将文件移动到的路径。好的,理解,谢谢!抱歉,必须远离键盘,因此示例不完整。它仍然不完整,但至少现在想法已经完全表达出来。另外,如果它们都位于程序运行的机器上,则不要使用SFTP,实际上您将在这种情况下,让解决方案变得更糟而不是更好。祝你好运。虽然这确实可行,但我认为你不需要两个SSH会话。它应该在一个SSH连接上只使用两个SFTP通道。一般来说,甚至一个SFTP通道就足够了。SFTP协议可以并行使用多个文件(读一个,写另一个)。但是我不确定,如果JSch SFTP实现是为了支持并行文件而构建的。@MartinPrikryl您可能是正确的,一个会话可能是可用的。我使用了两个会话,主要是因为将来,我希望会话从同一个帐户和机器迁移。我知道问题的提出使得从m同一个帐户和机器肯定不会发生,但由于他正在寻求一个网络协议,很可能有人计划移动这些东西,而他没有被告知全部情况(就像我们只有一台机器可以开发,但稍后我们会有三台)。也可能需要解释一下,为什么实际上需要下载并重新上载文件来复制它,而不是在服务器上就地复制它。还有其他选项,如使用
cp
shell命令(如果有shell访问权限)。请看,问题是关于SFTP。这不是SFTP解决方案。它依赖于shell访问。它依赖于平台。它仅在*nix服务器上工作。SFTP是通过SSH进行的文件传输。可以配置SSH服务和forbi