From 7e3ba710766baf4544fe6c2632c84d06154ca562 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 24 Jan 2021 23:04:49 +0800 Subject: [PATCH] fix FTP bug --- CHANGELOG.md | 1 + .../java/cn/hutool/extra/ftp/AbstractFtp.java | 2 +- .../main/java/cn/hutool/extra/ftp/Ftp.java | 83 +++++++++++-------- .../main/java/cn/hutool/extra/ssh/Sftp.java | 6 +- 4 files changed, 55 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b76d87c6..6f4d1c471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ * 【core 】 修复URLUtil.encodeAll未检查空指针问题(issue#I2CNPS@Gitee) * 【core 】 修复UrlBuilder.of的query中含有?丢失问题(issue#I2CNPS@Gitee) * 【crypto 】 修复BCrypt.checkpw报错问题(issue#1377@Github) +* 【extra 】 修复Fftp中cd失败导致的问题(issue#1371@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-extra/src/main/java/cn/hutool/extra/ftp/AbstractFtp.java b/hutool-extra/src/main/java/cn/hutool/extra/ftp/AbstractFtp.java index 24dbc333e..a26c791a1 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/ftp/AbstractFtp.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/ftp/AbstractFtp.java @@ -41,7 +41,7 @@ public abstract class AbstractFtp implements Closeable { public abstract AbstractFtp reconnectIfTimeout(); /** - * 打开指定目录 + * 打开指定目录,具体逻辑取决于实现,例如在FTP中,进入失败返回{@code false}, SFTP中则抛出异常 * * @param directory directory * @return 是否打开目录 diff --git a/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java b/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java index c64420034..536a99614 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java @@ -2,6 +2,7 @@ package cn.hutool.extra.ftp; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Filter; import cn.hutool.core.util.ArrayUtil; @@ -194,7 +195,7 @@ public class Ftp extends AbstractFtp { // 登录ftp服务器 client.login(config.getUser(), config.getPassword()); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } final int replyCode = client.getReplyCode(); // 是否成功登录服务器 if (false == FTPReply.isPositiveCompletion(replyCode)) { @@ -254,7 +255,7 @@ public class Ftp extends AbstractFtp { String pwd = null; try { pwd = pwd(); - } catch (FtpException fex) { + } catch (IORuntimeException fex) { // ignore } @@ -273,13 +274,14 @@ public class Ftp extends AbstractFtp { @Override public boolean cd(String directory) { if (StrUtil.isBlank(directory)) { - return false; + // 当前目录 + return true; } try { return client.changeWorkingDirectory(directory); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -294,7 +296,7 @@ public class Ftp extends AbstractFtp { try { return client.printWorkingDirectory(); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -334,21 +336,25 @@ public class Ftp extends AbstractFtp { /** * 遍历某个目录下所有文件和目录,不会递归遍历 * - * @param path 目录 + * @param path 目录,如果目录不存在,抛出异常 * @return 文件或目录列表 + * @throws FtpException 路径不存在 + * @throws IORuntimeException IO异常 */ - public FTPFile[] lsFiles(String path) { + public FTPFile[] lsFiles(String path) throws FtpException, IORuntimeException{ String pwd = null; if (StrUtil.isNotBlank(path)) { pwd = pwd(); - cd(path); + if(false == cd(path)){ + throw new FtpException("Change dir to [{}] error, maybe path not exist!"); + } } FTPFile[] ftpFiles; try { ftpFiles = this.client.listFiles(); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } finally { // 回到原目录 cd(pwd); @@ -358,11 +364,11 @@ public class Ftp extends AbstractFtp { } @Override - public boolean mkdir(String dir) { + public boolean mkdir(String dir) throws IORuntimeException{ try { return this.client.makeDirectory(dir); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -373,11 +379,11 @@ public class Ftp extends AbstractFtp { * @return 状态int,服务端不同,返回不同 * @since 5.4.3 */ - public int stat(String path) { + public int stat(String path) throws IORuntimeException{ try { return this.client.stat(path); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -386,28 +392,32 @@ public class Ftp extends AbstractFtp { * * @param path 文件路径 * @return 是否存在 + * @throws IORuntimeException IO异常 */ - public boolean existFile(String path) { + public boolean existFile(String path) throws IORuntimeException{ FTPFile[] ftpFileArr; try { ftpFileArr = client.listFiles(path); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } return ArrayUtil.isNotEmpty(ftpFileArr); } @Override - public boolean delFile(String path) { + public boolean delFile(String path) throws IORuntimeException{ final String pwd = pwd(); final String fileName = FileUtil.getName(path); final String dir = StrUtil.removeSuffix(path, fileName); - cd(dir); + if(false == cd(dir)){ + throw new FtpException("Change dir to [{}] error, maybe dir not exist!"); + } + boolean isSuccess; try { isSuccess = client.deleteFile(fileName); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } finally { // 回到原目录 cd(pwd); @@ -416,12 +426,12 @@ public class Ftp extends AbstractFtp { } @Override - public boolean delDir(String dirPath) { + public boolean delDir(String dirPath) throws IORuntimeException{ FTPFile[] dirs; try { dirs = client.listFiles(dirPath); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } String name; String childPath; @@ -442,7 +452,7 @@ public class Ftp extends AbstractFtp { try { return this.client.removeDirectory(dirPath); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -478,12 +488,13 @@ public class Ftp extends AbstractFtp { * @param path 服务端路径,可以为{@code null} 或者相对路径或绝对路径 * @param fileName 自定义在服务端保存的文件名 * @return 是否上传成功 + * @throws IORuntimeException IO异常 */ - public boolean upload(String path, String fileName, File file) { + public boolean upload(String path, String fileName, File file) throws IORuntimeException{ try (InputStream in = FileUtil.getInputStream(file)) { return upload(path, fileName, in); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -500,12 +511,13 @@ public class Ftp extends AbstractFtp { * @param fileName 文件名 * @param fileStream 文件流 * @return 是否上传成功 + * @throws IORuntimeException IO异常 */ - public boolean upload(String path, String fileName, InputStream fileStream) { + public boolean upload(String path, String fileName, InputStream fileStream) throws IORuntimeException{ try { client.setFileType(FTPClient.BINARY_FILE_TYPE); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } String pwd = null; @@ -515,16 +527,15 @@ public class Ftp extends AbstractFtp { if (StrUtil.isNotBlank(path)) { mkDirs(path); - boolean isOk = cd(path); - if (false == isOk) { - return false; + if (false == cd(path)) { + throw new FtpException("Change dir to [{}] error, maybe dir not exist!"); } } try { return client.storeFile(fileName, fileStream); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } finally { if (this.backToPwd) { cd(pwd); @@ -581,8 +592,9 @@ public class Ftp extends AbstractFtp { * @param path 文件路径 * @param fileName 文件名 * @param outFile 输出文件或目录 + * @throws IORuntimeException IO异常 */ - public void download(String path, String fileName, File outFile) { + public void download(String path, String fileName, File outFile) throws IORuntimeException{ if (outFile.isDirectory()) { outFile = new File(outFile, fileName); } @@ -592,7 +604,7 @@ public class Ftp extends AbstractFtp { try (OutputStream out = FileUtil.getOutputStream(outFile)) { download(path, fileName, out); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } } @@ -615,14 +627,17 @@ public class Ftp extends AbstractFtp { * @param out 输出位置 * @param fileNameCharset 文件名编码 * @since 5.5.7 + * @throws IORuntimeException IO异常 */ - public void download(String path, String fileName, OutputStream out, Charset fileNameCharset) { + public void download(String path, String fileName, OutputStream out, Charset fileNameCharset) throws IORuntimeException{ String pwd = null; if (this.backToPwd) { pwd = pwd(); } - cd(path); + if(false == cd(path)){ + throw new FtpException("Change dir to [{}] error, maybe dir not exist!"); + } if (null != fileNameCharset) { fileName = new String(fileName.getBytes(fileNameCharset), StandardCharsets.ISO_8859_1); @@ -631,7 +646,7 @@ public class Ftp extends AbstractFtp { client.setFileType(FTPClient.BINARY_FILE_TYPE); client.retrieveFile(fileName, out); } catch (IOException e) { - throw new FtpException(e); + throw new IORuntimeException(e); } finally { if (backToPwd) { cd(pwd); diff --git a/hutool-extra/src/main/java/cn/hutool/extra/ssh/Sftp.java b/hutool-extra/src/main/java/cn/hutool/extra/ssh/Sftp.java index c13e7b0c9..60bf2777a 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/ssh/Sftp.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/ssh/Sftp.java @@ -7,6 +7,7 @@ import cn.hutool.core.lang.Filter; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.ftp.AbstractFtp; import cn.hutool.extra.ftp.FtpConfig; +import cn.hutool.extra.ftp.FtpException; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelSftp.LsEntry; import com.jcraft.jsch.ChannelSftp.LsEntrySelector; @@ -323,9 +324,10 @@ public class Sftp extends AbstractFtp { * * @param directory directory * @return 是否打开目录 + * @throws FtpException 进入目录失败异常 */ @Override - public boolean cd(String directory) { + public boolean cd(String directory) throws FtpException{ if (StrUtil.isBlank(directory)) { // 当前目录 return true; @@ -334,7 +336,7 @@ public class Sftp extends AbstractFtp { channel.cd(directory.replaceAll("\\\\", "/")); return true; } catch (SftpException e) { - return false; + throw new FtpException(e); } }