fix FTP bug

This commit is contained in:
Looly 2021-01-24 23:04:49 +08:00
parent 221608b544
commit 7e3ba71076
4 changed files with 55 additions and 37 deletions

View File

@ -22,6 +22,7 @@
* 【core 】 修复URLUtil.encodeAll未检查空指针问题issue#I2CNPS@Gitee * 【core 】 修复URLUtil.encodeAll未检查空指针问题issue#I2CNPS@Gitee
* 【core 】 修复UrlBuilder.of的query中含有?丢失问题issue#I2CNPS@Gitee * 【core 】 修复UrlBuilder.of的query中含有?丢失问题issue#I2CNPS@Gitee
* 【crypto 】 修复BCrypt.checkpw报错问题issue#1377@Github * 【crypto 】 修复BCrypt.checkpw报错问题issue#1377@Github
* 【extra 】 修复Fftp中cd失败导致的问题issue#1371@Github
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@ -41,7 +41,7 @@ public abstract class AbstractFtp implements Closeable {
public abstract AbstractFtp reconnectIfTimeout(); public abstract AbstractFtp reconnectIfTimeout();
/** /**
* 打开指定目录 * 打开指定目录具体逻辑取决于实现例如在FTP中进入失败返回{@code false} SFTP中则抛出异常
* *
* @param directory directory * @param directory directory
* @return 是否打开目录 * @return 是否打开目录

View File

@ -2,6 +2,7 @@ package cn.hutool.extra.ftp;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Filter; import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
@ -194,7 +195,7 @@ public class Ftp extends AbstractFtp {
// 登录ftp服务器 // 登录ftp服务器
client.login(config.getUser(), config.getPassword()); client.login(config.getUser(), config.getPassword());
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
final int replyCode = client.getReplyCode(); // 是否成功登录服务器 final int replyCode = client.getReplyCode(); // 是否成功登录服务器
if (false == FTPReply.isPositiveCompletion(replyCode)) { if (false == FTPReply.isPositiveCompletion(replyCode)) {
@ -254,7 +255,7 @@ public class Ftp extends AbstractFtp {
String pwd = null; String pwd = null;
try { try {
pwd = pwd(); pwd = pwd();
} catch (FtpException fex) { } catch (IORuntimeException fex) {
// ignore // ignore
} }
@ -273,13 +274,14 @@ public class Ftp extends AbstractFtp {
@Override @Override
public boolean cd(String directory) { public boolean cd(String directory) {
if (StrUtil.isBlank(directory)) { if (StrUtil.isBlank(directory)) {
return false; // 当前目录
return true;
} }
try { try {
return client.changeWorkingDirectory(directory); return client.changeWorkingDirectory(directory);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
} }
@ -294,7 +296,7 @@ public class Ftp extends AbstractFtp {
try { try {
return client.printWorkingDirectory(); return client.printWorkingDirectory();
} catch (IOException e) { } 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 文件或目录列表 * @return 文件或目录列表
* @throws FtpException 路径不存在
* @throws IORuntimeException IO异常
*/ */
public FTPFile[] lsFiles(String path) { public FTPFile[] lsFiles(String path) throws FtpException, IORuntimeException{
String pwd = null; String pwd = null;
if (StrUtil.isNotBlank(path)) { if (StrUtil.isNotBlank(path)) {
pwd = pwd(); pwd = pwd();
cd(path); if(false == cd(path)){
throw new FtpException("Change dir to [{}] error, maybe path not exist!");
}
} }
FTPFile[] ftpFiles; FTPFile[] ftpFiles;
try { try {
ftpFiles = this.client.listFiles(); ftpFiles = this.client.listFiles();
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} finally { } finally {
// 回到原目录 // 回到原目录
cd(pwd); cd(pwd);
@ -358,11 +364,11 @@ public class Ftp extends AbstractFtp {
} }
@Override @Override
public boolean mkdir(String dir) { public boolean mkdir(String dir) throws IORuntimeException{
try { try {
return this.client.makeDirectory(dir); return this.client.makeDirectory(dir);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
} }
@ -373,11 +379,11 @@ public class Ftp extends AbstractFtp {
* @return 状态int服务端不同返回不同 * @return 状态int服务端不同返回不同
* @since 5.4.3 * @since 5.4.3
*/ */
public int stat(String path) { public int stat(String path) throws IORuntimeException{
try { try {
return this.client.stat(path); return this.client.stat(path);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
} }
@ -386,28 +392,32 @@ public class Ftp extends AbstractFtp {
* *
* @param path 文件路径 * @param path 文件路径
* @return 是否存在 * @return 是否存在
* @throws IORuntimeException IO异常
*/ */
public boolean existFile(String path) { public boolean existFile(String path) throws IORuntimeException{
FTPFile[] ftpFileArr; FTPFile[] ftpFileArr;
try { try {
ftpFileArr = client.listFiles(path); ftpFileArr = client.listFiles(path);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
return ArrayUtil.isNotEmpty(ftpFileArr); return ArrayUtil.isNotEmpty(ftpFileArr);
} }
@Override @Override
public boolean delFile(String path) { public boolean delFile(String path) throws IORuntimeException{
final String pwd = pwd(); final String pwd = pwd();
final String fileName = FileUtil.getName(path); final String fileName = FileUtil.getName(path);
final String dir = StrUtil.removeSuffix(path, fileName); 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; boolean isSuccess;
try { try {
isSuccess = client.deleteFile(fileName); isSuccess = client.deleteFile(fileName);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} finally { } finally {
// 回到原目录 // 回到原目录
cd(pwd); cd(pwd);
@ -416,12 +426,12 @@ public class Ftp extends AbstractFtp {
} }
@Override @Override
public boolean delDir(String dirPath) { public boolean delDir(String dirPath) throws IORuntimeException{
FTPFile[] dirs; FTPFile[] dirs;
try { try {
dirs = client.listFiles(dirPath); dirs = client.listFiles(dirPath);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
String name; String name;
String childPath; String childPath;
@ -442,7 +452,7 @@ public class Ftp extends AbstractFtp {
try { try {
return this.client.removeDirectory(dirPath); return this.client.removeDirectory(dirPath);
} catch (IOException e) { } 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 path 服务端路径可以为{@code null} 或者相对路径或绝对路径
* @param fileName 自定义在服务端保存的文件名 * @param fileName 自定义在服务端保存的文件名
* @return 是否上传成功 * @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)) { try (InputStream in = FileUtil.getInputStream(file)) {
return upload(path, fileName, in); return upload(path, fileName, in);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
} }
@ -500,12 +511,13 @@ public class Ftp extends AbstractFtp {
* @param fileName 文件名 * @param fileName 文件名
* @param fileStream 文件流 * @param fileStream 文件流
* @return 是否上传成功 * @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 { try {
client.setFileType(FTPClient.BINARY_FILE_TYPE); client.setFileType(FTPClient.BINARY_FILE_TYPE);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
String pwd = null; String pwd = null;
@ -515,16 +527,15 @@ public class Ftp extends AbstractFtp {
if (StrUtil.isNotBlank(path)) { if (StrUtil.isNotBlank(path)) {
mkDirs(path); mkDirs(path);
boolean isOk = cd(path); if (false == cd(path)) {
if (false == isOk) { throw new FtpException("Change dir to [{}] error, maybe dir not exist!");
return false;
} }
} }
try { try {
return client.storeFile(fileName, fileStream); return client.storeFile(fileName, fileStream);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} finally { } finally {
if (this.backToPwd) { if (this.backToPwd) {
cd(pwd); cd(pwd);
@ -581,8 +592,9 @@ public class Ftp extends AbstractFtp {
* @param path 文件路径 * @param path 文件路径
* @param fileName 文件名 * @param fileName 文件名
* @param outFile 输出文件或目录 * @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()) { if (outFile.isDirectory()) {
outFile = new File(outFile, fileName); outFile = new File(outFile, fileName);
} }
@ -592,7 +604,7 @@ public class Ftp extends AbstractFtp {
try (OutputStream out = FileUtil.getOutputStream(outFile)) { try (OutputStream out = FileUtil.getOutputStream(outFile)) {
download(path, fileName, out); download(path, fileName, out);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} }
} }
@ -615,14 +627,17 @@ public class Ftp extends AbstractFtp {
* @param out 输出位置 * @param out 输出位置
* @param fileNameCharset 文件名编码 * @param fileNameCharset 文件名编码
* @since 5.5.7 * @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; String pwd = null;
if (this.backToPwd) { if (this.backToPwd) {
pwd = pwd(); pwd = pwd();
} }
cd(path); if(false == cd(path)){
throw new FtpException("Change dir to [{}] error, maybe dir not exist!");
}
if (null != fileNameCharset) { if (null != fileNameCharset) {
fileName = new String(fileName.getBytes(fileNameCharset), StandardCharsets.ISO_8859_1); 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.setFileType(FTPClient.BINARY_FILE_TYPE);
client.retrieveFile(fileName, out); client.retrieveFile(fileName, out);
} catch (IOException e) { } catch (IOException e) {
throw new FtpException(e); throw new IORuntimeException(e);
} finally { } finally {
if (backToPwd) { if (backToPwd) {
cd(pwd); cd(pwd);

View File

@ -7,6 +7,7 @@ import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.ftp.AbstractFtp; import cn.hutool.extra.ftp.AbstractFtp;
import cn.hutool.extra.ftp.FtpConfig; import cn.hutool.extra.ftp.FtpConfig;
import cn.hutool.extra.ftp.FtpException;
import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry; import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.ChannelSftp.LsEntrySelector; import com.jcraft.jsch.ChannelSftp.LsEntrySelector;
@ -323,9 +324,10 @@ public class Sftp extends AbstractFtp {
* *
* @param directory directory * @param directory directory
* @return 是否打开目录 * @return 是否打开目录
* @throws FtpException 进入目录失败异常
*/ */
@Override @Override
public boolean cd(String directory) { public boolean cd(String directory) throws FtpException{
if (StrUtil.isBlank(directory)) { if (StrUtil.isBlank(directory)) {
// 当前目录 // 当前目录
return true; return true;
@ -334,7 +336,7 @@ public class Sftp extends AbstractFtp {
channel.cd(directory.replaceAll("\\\\", "/")); channel.cd(directory.replaceAll("\\\\", "/"));
return true; return true;
} catch (SftpException e) { } catch (SftpException e) {
return false; throw new FtpException(e);
} }
} }