Java SFTP传输文件实例

原文地址:www.baeldung.com/java-file-sftp


1. 概述

  这篇文章将介绍如何用 Java 在远程服务器上通过 SFTP 上传和下载文件。
  接下来将使用三种不同的开发库实现,分别是 JSch、SSHJ 和 Apache Commons VFS。

  

2. 使用JSch

  首先,让我们看看如何使用 JSch 在远程服务器上实现文件上传和下载。

  

2.1 Maven 配置

  在项目 pom.xml 中添加 jsch 依赖:

1
2
3
4
5
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>

  在 Maven 中央仓库可以找到 jsch 的最新版本。

  

2.2. 配置 JSch

  现在开始配置 JSch。

  JSch 支持密码或公共密钥认证访问远程服务器。下面的示例采用密码认证:

1
2
3
4
5
6
7
8
private ChannelSftp setupJsch() throws JSchException {
JSch jsch = new JSch();
jsch.setKnownHosts("/Users/john/.ssh/known_hosts");
Session jschSession = jsch.getSession(username, remoteHost);
jschSession.setPassword(password);
jschSession.connect();
return (ChannelSftp) jschSession.openChannel("sftp");
}

  在这个示例中,remoteHost 表示成服务器的名称或 IP 地址(例如 example.com)。在测试中可以像下面这样定义:

1
2
3
private String remoteHost = "HOST_NAME_HERE";
private String username = "USERNAME_HERE";
private String password = "PASSWORD_HERE";

  还以用下面的命令生成 known_hosts 文件:

1
ssh-keyscan -H -t rsa REMOTE_HOSTNAME >> known_hosts

  

2.3. 使用 JSch 上传文件

  调用ChannelSftp.put() 可以上传文件到远程服务器:

1
2
3
4
5
6
7
8
9
@Test
public void whenUploadFileUsingJsch_thenSuccess() throws JSchException, SftpException {
ChannelSftp channelSftp = setupJsch();
channelSftp.connect();
String localFile = "src/main/resources/sample.txt";
String remoteDir = "remote_sftp_test/";
channelSftp.put(localFile, remoteDir + "jschFile.txt");
channelSftp.exit();
}

  在这个示例中,第一个参数代表要上传的本地文件,比如 src/main/resources/sample.txt;`remoteDir` 表示待上传的远程服务器路径。

  

2.4. 使用 JSch 下载文件

  还可以使用 ChannelSftp.get() 从远程服务器上下载文件:

1
2
3
4
5
6
7
8
9
@Test
public void whenDownloadFileUsingJsch_thenSuccess() throws JSchException, SftpException {
ChannelSftp channelSftp = setupJsch();
channelSftp.connect();
String remoteFile = "welcome.txt";
String localDir = "src/main/resources/";
channelSftp.get(remoteFile, localDir + "jschFile.txt");
channelSftp.exit();
}

  remoteFile 表示要要下载的文件路径,localDir 表示下载到本地的文件路径。

  

3. 使用 SSHJ

  接下来,我们将使用 SSHJ 库在远程服务器上实现文件上传和下载。

  

3.1. Maven 配置

  首先,在项目 pom.xml 中添加依赖:

1
2
3
4
5
<dependency>
<groupId>com.hierynomus</groupId>
<artifactId>sshj</artifactId>
<version>0.27.0</version>
</dependency>

  在 Maven 中央仓库可以找到 sshj 的最新版本。

  

3.2. 配置 SSHJ

  接下来配置 SSHClient。

  SSHJ 同样支持密码或公共密钥认证访问远程服务器。下面的示例采用密码认证:

1
2
3
4
5
6
7
private SSHClient setupSshj() throws IOException {
SSHClient client = new SSHClient();
client.addHostKeyVerifier(new PromiscuousVerifier());
client.connect(remoteHost);
client.authPassword(username, password);
return client;
}

  

3.3. 使用 SSHJ 上传文件

  与 JSch 类似,调用 SFTPClient.put() 可以上传文件到远程服务器:

1
2
3
4
5
6
7
8
@Test
public void whenUploadFileUsingSshj_thenSuccess() throws IOException {
SSHClient sshClient = setupSshj();
SFTPClient sftpClient = sshClient.newSFTPClient();
sftpClient.put(localFile, remoteDir + "sshjFile.txt");
sftpClient.close();
sshClient.disconnect();
}

  这里定义两个新变量:

1
2
private String localFile = "src/main/resources/input.txt";
private String remoteDir = "remote_sftp_test/";

  

3.4. 使用 SSHJ 下载文件

  同样,这里用 SFTPClient.get() 从远程服务器上下载文件。

1
2
3
4
5
6
7
8
@Test
public void whenDownloadFileUsingSshj_thenSuccess() throws IOException {
SSHClient sshClient = setupSshj();
SFTPClient sftpClient = sshClient.newSFTPClient();
sftpClient.get(remoteFile, localDir + "sshjFile.txt");
sftpClient.close();
sshClient.disconnect();
}

  添加两个前面用到的变量:

1
2
private String remoteFile = "welcome.txt";
private String localDir = "src/main/resources/";

  

4. 使用 Apache Commons VFS

  最后,使用 Apache Commons VFS 与远程服务器传送文件。
  实际上,Apache Commons VFS 内部使用了 JSch 库。

  

4.1. Maven 配置

  需要在项目 pom.xml 中添加 commons-vfs2 依赖:

1
2
3
4
5
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.4</version>
</dependency>

  在 Maven 中央仓库可以找到 commons-vfs2 的最新版本。

  

4.2. 使用 Apache Commons VFS 下载文件

  Apache Commons VFS 的用法略有不同。

  FileSystemManager为目标文件创建FileObjects 对象,然后发送。

  在这个示例中,调用 FileObject.copyFrom() 上传文件。

1
2
3
4
5
6
7
8
9
10
11
@Test
public void whenUploadFileUsingVfs_thenSuccess() throws IOException {
FileSystemManager manager = VFS.getManager();
FileObject local = manager.resolveFile(
System.getProperty("user.dir") + "/" + localFile);
FileObject remote = manager.resolveFile(
"sftp://" + username + ":" + password + "@" + remoteHost + "/" + remoteDir + "vfsFile.txt");
remote.copyFrom(local, Selectors.SELECT_SELF);
local.close();
remote.close();
}

  注意:本地文件应该使用绝对路径,远程文件路径应该以 sftp://username:password@remoteHost 开始。

  

4.3. 使用 Apache Commons VFS 下载文件

  从远程服务器上下载文件用法类似,还是用 FileObject.copyFrom() 从 remoteFile 拷贝到 localFile:

1
2
3
4
5
6
7
8
9
10
11
@Test
public void whenDownloadFileUsingVfs_thenSuccess() throws IOException {
FileSystemManager manager = VFS.getManager();
FileObject local = manager.resolveFile(
System.getProperty("user.dir") + "/" + localDir + "vfsFile.txt");
FileObject remote = manager.resolveFile(
"sftp://" + username + ":" + password + "@" + remoteHost + "/" + remoteFile);
local.copyFrom(remote, Selectors.SELECT_SELF);
local.close();
remote.close();
}

  

5. 总结

  这篇文章中,我们学习了如何用 Java 从远程 SFTP 服务器上载和下载文件。为此,我们使用了 JSch、SSHJ 和 Apache Commons VFS 多个开发库。

  完整的示例源代码可以在 GitHub 上找到:
github.com/eugenp/tutorials/tree/master/libraries-io

---------------- The End ----------------
0%