Hutool SFTP操作完整指南
一、环境准备与依赖配置
1、添加依赖
Maven配置(推荐5.8.16+版本):
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
二、SFTP连接管理
1、创建连接(单例模式 - 不推荐并发)
// 默认重用Session,并发时一个线程关闭连接会导致其他线程失败
Sftp sftp = new Sftp("host", 22, "user", "password");
2、创建连接(多例模式 - 并发安全)
Session session = JschUtil.createSession("host", 22, "user", "password");
Sftp sftp = new Sftp(session); // 每个线程独立Session
3、关闭连接
sftp.close(); // 断开SFTP通道(若Session非共享,则同时关闭Session)
三、文件上传
1、上传文件
| 方法签名 | 说明 |
|---|---|
put(String srcFilePath, String destPath) | 本地文件 → 远程路径(自动覆盖) |
put(String srcFilePath, String destPath, Sftp.Mode mode) | 指定传输模式(覆盖/追加/恢复) |
put(InputStream srcStream, String destPath, Sftp.Mode mode) | 流数据直接上传 |
示例:
sftp.download("/remote/test.txt", "/local/"); // 下载到本地目录
2. 下载文件
| 方法签名 | 说明 |
|---|---|
download(String remotePath, String localPath) | 远程文件 → 本地路径 |
download(String remotePath, OutputStream out) | 下载到输出流 |
示例:
sftp.download("/remote/test.txt", "/local/"); // 下载到本地目录
3. 删除文件
| 方法签名 | 说明 |
|---|---|
delFile(String remoteFilePath) | 删除单个文件(路径不存在则抛异常) |
delDir(String remoteDirPath) | 递归删除空目录 |
四、目录操作
1. 创建目录
sftp.mkdir("/remote/newdir"); // 创建单级目录
sftp.mkDirs("/remote/parent/child"); // 递归创建多级目录
2. 遍历目录
List<String> files = sftp.ls("/remote"); // 返回文件名列表
Vector<ChannelSftp.LsEntry> details = sftp.lsEntries("/remote"); // 获取详细属性
3. 递归下载目录
// 自定义工具类方法
public static void downloadDir(Sftp sftp, String remotePath, String localPath) {
Vector<ChannelSftp.LsEntry> files = sftp.lsEntries(remotePath);
for (ChannelSftp.LsEntry entry : files) {
if (entry.getAttrs().isDir()) {
// 递归子目录
downloadDir(sftp, remotePath + "/" + entry.getFilename(), localPath);
} else {
sftp.download(remotePath + "/" + entry.getFilename(), localPath);
}
}
}
五、高级特性
1. 传输模式(Sftp.Mode)
OVERWRITE:覆盖目标文件(默认)RESUME:断点续传(追加未完成部分)APPEND:数据追加到文件末尾
2. 进度监控
sftp.put("/local/bigfile.zip", "/remote/",
new MyProgressMonitor(), Mode.RESUME); // 自定义进度条实现
需实现com.jcraft.jsch.SftpProgressMonitor接口
3. 并发使用注意事项
避免共享Session,并发场景必须通过独立Session创建Sftp对象:
// 正确做法(每个线程独立Session)
Session session = JschUtil.openSession(host, port, user, pass);
Sftp sftp = new Sftp(session);
六、错误处理与最佳实践
1. 常见异常
SftpException: 路径不存在/权限不足JschException: 认证失败/网络中断
2. 资源释放
务必在finally块中关闭连接:
try {
sftp.upload(...);
} finally {
if(sftp != null) sftp.close();
}
3. 路径规范
使用StrUtil.appendIfMissing(path, "/")确保路径以/结尾,避免拼接错误。
七、完整示例代码
import cn.hutool.extra.ssh.JschUtil;
import cn.hutool.extra.ssh.Sftp;
import com.jcraft.jsch.Session;
public class SftpExample {
private static final String host = "1.2.3.4";
private static final String user = "root";
private static final String password = "123456";
private static final int port = 22;
public static void main(String[] args) {
// 1. 创建SFTP连接(多例模式)
Session session = JschUtil.createSession(host,port,user,password);
Sftp sftp = new Sftp(session);
try {
// 2. 创建远程目录
sftp.mkDirs("/remote/data");
// 3. 上传文件(覆盖模式)
sftp.put("local/file.txt", "/remote/data/file.txt", Sftp.Mode.OVERWRITE);
// 4. 下载文件
sftp.download("/remote/data/file.txt", "local/download/");
// 5. 递归下载目录
downloadDir(sftp, "/remote/data", "local/download/");
} catch (Exception e) {
System.err.println("SFTP操作失败: " + e.getMessage());
} finally {
// 6. 确保关闭连接
if (sftp != null) {
sftp.close();
}
}
}
// 递归下载目录方法
public static void downloadDir(Sftp sftp, String remotePath, String localPath) {
Vector<ChannelSftp.LsEntry> files = sftp.lsEntries(remotePath);
for (ChannelSftp.LsEntry entry : files) {
String filename = entry.getFilename();
if (".".equals(filename) || "..".equals(filename)) continue;
String remoteFullPath = remotePath + "/" + filename;
String localFullPath = localPath + "/" + filename;
if (entry.getAttrs().isDir()) {
// 创建本地目录并递归下载
new File(localFullPath).mkdirs();
downloadDir(sftp, remoteFullPath, localFullPath);
} else {
sftp.download(remoteFullPath, localFullPath);
}
}
}
}
八、常见问题解决
1. 连接超时问题
// 设置超时时间(毫秒)
Session session = JschUtil.createSession("host", 22, "user", "password");
session.setTimeout(30000); // 30秒超时
Sftp sftp = new Sftp(session);
2. 权限不足问题
确保远程服务器用户有相应权限,或使用sudo权限用户
3. 中文乱码问题
// 设置编码
Sftp sftp = new Sftp("host", 22, "user", "password");
sftp.setCharset("UTF-8");
4. 文件锁问题
上传大文件时,使用断点续传模式避免文件锁定:
sftp.put("largefile.zip", "/remote/", Mode.RESUME);
九、性能优化建议
- 连接池管理 - 高并发场景使用连接池
- 批量操作 - 尽量减少连接次数
- 缓冲区调整 - 传输大文件时增大缓冲区
- 并行传输 - 多线程下载大文件
597

被折叠的 条评论
为什么被折叠?



