From 11fc24370544497ce1f342d729b901ecc00fcbfc Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 12 May 2025 12:08:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3pwd=E3=80=81cd=E8=B0=83?= =?UTF-8?q?=E7=94=A8command=E5=AF=BC=E8=87=B4=E4=BB=85SftpSubsystem?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=97=B6=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/v7/extra/ftp/CommonsFtp.java | 6 +- .../main/java/cn/hutool/v7/extra/ftp/Ftp.java | 4 +- .../v7/extra/ssh/engine/jsch/JschSftp.java | 6 +- .../v7/extra/ssh/engine/sshj/SshjSftp.java | 112 +++++++++++++----- 4 files changed, 90 insertions(+), 38 deletions(-) diff --git a/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/CommonsFtp.java b/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/CommonsFtp.java index 12d92e7ec..30274dae6 100644 --- a/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/CommonsFtp.java +++ b/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/CommonsFtp.java @@ -648,17 +648,17 @@ public class CommonsFtp extends AbstractFtp { * 递归下载FTP服务器上文件到本地(文件目录和服务器同步) * * @param sourcePath ftp服务器目录 - * @param destDir 本地目录 + * @param targetDir 本地目录 */ @Override - public void recursiveDownloadFolder(final String sourcePath, final File destDir) { + public void recursiveDownloadFolder(final String sourcePath, final File targetDir) { String fileName; String srcFile; File destFile; for (final FTPFile ftpFile : lsFiles(sourcePath, null)) { fileName = ftpFile.getName(); srcFile = StrUtil.format("{}/{}", sourcePath, fileName); - destFile = FileUtil.file(destDir, fileName); + destFile = FileUtil.file(targetDir, fileName); if (!ftpFile.isDirectory()) { // 本地不存在文件或者ftp上文件有修改则下载 diff --git a/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/Ftp.java b/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/Ftp.java index bf53c50d9..252bf117f 100644 --- a/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/Ftp.java +++ b/hutool-extra/src/main/java/cn/hutool/v7/extra/ftp/Ftp.java @@ -174,10 +174,10 @@ public interface Ftp extends Closeable { * 递归下载FTP服务器上文件到本地(文件目录和服务器同步), 服务器上有新文件会覆盖本地文件 * * @param sourcePath ftp服务器目录 - * @param destDir 本地目录 + * @param targetDir 本地目录 * @since 5.3.5 */ - void recursiveDownloadFolder(String sourcePath, File destDir); + void recursiveDownloadFolder(String sourcePath, File targetDir); /** * 读取FTP服务器上的文件为输入流 diff --git a/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/jsch/JschSftp.java b/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/jsch/JschSftp.java index bd220cb2d..1aadcab84 100644 --- a/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/jsch/JschSftp.java +++ b/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/jsch/JschSftp.java @@ -593,17 +593,17 @@ public class JschSftp extends AbstractFtp { * 递归下载FTP服务器上文件到本地(文件目录和服务器同步) * * @param sourcePath ftp服务器目录,必须为目录 - * @param destDir 本地目录 + * @param targetDir 本地目录 */ @Override - public void recursiveDownloadFolder(final String sourcePath, final File destDir) throws SshException { + public void recursiveDownloadFolder(final String sourcePath, final File targetDir) throws SshException { String fileName; String srcFile; File destFile; for (final LsEntry item : lsEntries(sourcePath)) { fileName = item.getFilename(); srcFile = StrUtil.format("{}/{}", sourcePath, fileName); - destFile = FileUtil.file(destDir, fileName); + destFile = FileUtil.file(targetDir, fileName); if (!item.getAttrs().isDir()) { // 本地不存在文件或者ftp上文件有修改则下载 diff --git a/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/sshj/SshjSftp.java b/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/sshj/SshjSftp.java index 52125026b..c7adedf3c 100644 --- a/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/sshj/SshjSftp.java +++ b/hutool-extra/src/main/java/cn/hutool/v7/extra/ssh/engine/sshj/SshjSftp.java @@ -16,20 +16,21 @@ package cn.hutool.v7.extra.ssh.engine.sshj; +import cn.hutool.v7.core.collection.CollUtil; +import cn.hutool.v7.core.io.IORuntimeException; +import cn.hutool.v7.core.io.IoUtil; +import cn.hutool.v7.core.io.file.FileUtil; +import cn.hutool.v7.core.text.StrUtil; +import cn.hutool.v7.extra.ftp.AbstractFtp; +import cn.hutool.v7.extra.ftp.FtpConfig; +import cn.hutool.v7.extra.ftp.FtpException; +import cn.hutool.v7.extra.ssh.Connector; import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.connection.channel.direct.Session; import net.schmizz.sshj.sftp.RemoteFile; import net.schmizz.sshj.sftp.RemoteResourceInfo; import net.schmizz.sshj.sftp.SFTPClient; import net.schmizz.sshj.xfer.FileSystemFile; -import cn.hutool.v7.core.collection.CollUtil; -import cn.hutool.v7.core.io.IORuntimeException; -import cn.hutool.v7.core.io.IoUtil; -import cn.hutool.v7.core.text.StrUtil; -import cn.hutool.v7.extra.ftp.AbstractFtp; -import cn.hutool.v7.extra.ftp.FtpConfig; -import cn.hutool.v7.extra.ftp.FtpException; -import cn.hutool.v7.extra.ssh.Connector; import java.io.File; import java.io.IOException; @@ -51,6 +52,7 @@ import java.util.List; public class SshjSftp extends AbstractFtp { // region ----- of + /** * 构造 * @@ -94,6 +96,7 @@ public class SshjSftp extends AbstractFtp { private SSHClient ssh; private SFTPClient sftp; private Session session; + private String workingDir; /** * 构造 @@ -125,7 +128,7 @@ public class SshjSftp extends AbstractFtp { * @since 5.7.18 */ public void init() { - if(null == this.ssh){ + if (null == this.ssh) { this.ssh = SshjUtil.openClient(this.ftpConfig.getConnector()); } @@ -153,32 +156,41 @@ public class SshjSftp extends AbstractFtp { @Override public boolean cd(final String directory) { - final String exec = String.format("cd %s", directory); - command(exec); - final String pwd = pwd(); - return pwd.equals(directory); +// final String exec = String.format("cd %s", directory); +// command(exec); +// final String pwd = pwd(); +// return pwd.equals(directory); + String newPath = getPath(directory); + try { + sftp.ls(newPath); + this.workingDir = newPath; + return true; + } catch (IOException e) { + throw new FtpException(e); + } } @Override public String pwd() { - return command("pwd"); +// return command("pwd"); + return getPath(null); } @Override public boolean mkdir(final String dir) { try { - sftp.mkdir(dir); + sftp.mkdir(getPath(dir)); } catch (final IOException e) { throw new FtpException(e); } - return containsFile(dir); + return containsFile(getPath(dir)); } @Override public List ls(final String path) { final List infoList; try { - infoList = sftp.ls(path); + infoList = sftp.ls(getPath(path)); } catch (final IOException e) { throw new FtpException(e); } @@ -201,8 +213,8 @@ public class SshjSftp extends AbstractFtp { @Override public boolean delFile(final String path) { try { - sftp.rm(path); - return !containsFile(path); + sftp.rm(getPath(path)); + return !containsFile(getPath(path)); } catch (final IOException e) { throw new FtpException(e); } @@ -211,18 +223,21 @@ public class SshjSftp extends AbstractFtp { @Override public boolean delDir(final String dirPath) { try { - sftp.rmdir(dirPath); - return !containsFile(dirPath); + sftp.rmdir(getPath(dirPath)); + return !containsFile(getPath(dirPath)); } catch (final IOException e) { throw new FtpException(e); } } @Override - public boolean uploadFile(final String destPath, final File file) { + public boolean uploadFile(String destPath, final File file) { try { - sftp.put(new FileSystemFile(file), destPath); - return containsFile(destPath); + if (StrUtil.endWith(destPath, StrUtil.SLASH)) { + destPath += file.getName(); + } + sftp.put(new FileSystemFile(file), getPath(destPath)); + return containsFile(getPath(destPath)); } catch (final IOException e) { throw new FtpException(e); } @@ -231,17 +246,25 @@ public class SshjSftp extends AbstractFtp { @Override public void download(final String path, final File outFile) { try { - sftp.get(path, new FileSystemFile(outFile)); + sftp.get(getPath(path), new FileSystemFile(outFile)); } catch (final IOException e) { throw new FtpException(e); } } @Override - public void recursiveDownloadFolder(final String sourcePath, final File destDir) { - final List files = ls(sourcePath); - if (files != null && !files.isEmpty()) { - files.forEach(path -> download(sourcePath + "/" + path, destDir)); + public void recursiveDownloadFolder(final String sourcePath, final File targetDir) { + if (!targetDir.exists()) { + if (!targetDir.mkdirs()) { + throw new FtpException("Dir {} create failed!", targetDir.getAbsolutePath()); + } + }else if(!targetDir.isDirectory()){ + throw new FtpException("Target is not a directory!"); + } + + List files = ls(getPath(sourcePath)); + if (CollUtil.isNotEmpty(files)) { + files.forEach(file -> download(sourcePath + StrUtil.SLASH + file, FileUtil.file(targetDir, file))); } } @@ -280,7 +303,7 @@ public class SshjSftp extends AbstractFtp { */ public boolean containsFile(final String fileDir) { try { - sftp.lstat(fileDir); + sftp.lstat(getPath(fileDir)); return true; } catch (final IOException e) { return false; @@ -329,4 +352,33 @@ public class SshjSftp extends AbstractFtp { } return session; } + + /** + * 获取对应路径的绝对路径
+ * 如果提供的为绝对路径,直接返回,否则拼接当前路径 + * + * @param path 路径 + * @return 绝对路径 + */ + private String getPath(final String path) { + if (StrUtil.isBlank(this.workingDir)) { + try { + this.workingDir = sftp.canonicalize(StrUtil.EMPTY); + } catch (IOException e) { + throw new FtpException(e); + } + } + + if (StrUtil.isBlank(path)) { + return this.workingDir; + } + + // 如果是绝对路径,则返回 + if (StrUtil.startWith(path, StrUtil.SLASH)) { + return path; + } + + final String tmp = StrUtil.removeSuffix(this.workingDir, StrUtil.SLASH); + return StrUtil.format("{}/{}", tmp, path); + } }