mirror of https://github.com/elunez/eladmin
				
				
				
			支持FTP工具类
							parent
							
								
									332cf6c5fa
								
							
						
					
					
						commit
						911c4c092b
					
				| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <properties>
 | 
			
		||||
        <hutool.version>5.8.35</hutool.version>
 | 
			
		||||
        <commons-net.version>3.7</commons-net.version>
 | 
			
		||||
    </properties>
 | 
			
		||||
 | 
			
		||||
    <artifactId>eladmin-common</artifactId>
 | 
			
		||||
| 
						 | 
				
			
			@ -20,5 +21,11 @@
 | 
			
		|||
            <artifactId>hutool-all</artifactId>
 | 
			
		||||
            <version>${hutool.version}</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <!-- 用于FTP -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>commons-net</groupId>
 | 
			
		||||
            <artifactId>commons-net</artifactId>
 | 
			
		||||
            <version>${commons-net.version}</version> <!-- 版本号可能会有更新 -->
 | 
			
		||||
        </dependency>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
</project>
 | 
			
		||||
| 
						 | 
				
			
			@ -17,9 +17,13 @@ package me.zhengjie.config.properties;
 | 
			
		|||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import me.zhengjie.utils.ElConstant;
 | 
			
		||||
import me.zhengjie.utils.EncryptUtils;
 | 
			
		||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Zheng Jie
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -57,4 +61,76 @@ public class FileProperties {
 | 
			
		|||
 | 
			
		||||
        private String avatar;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // region 支持FTP配置
 | 
			
		||||
    private FtpConfig ftp;
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    public static class FtpConfig {
 | 
			
		||||
        private String host;
 | 
			
		||||
        private int port;
 | 
			
		||||
        private String username;
 | 
			
		||||
        private String password;
 | 
			
		||||
        private String mainPath;
 | 
			
		||||
        private int connectTimeout = 5000;    // ms
 | 
			
		||||
        private int dataTimeout = 30000;    // ms
 | 
			
		||||
        // 连接池相关配置
 | 
			
		||||
        private int minIdle = 1;
 | 
			
		||||
        private int maxIdle = 3;
 | 
			
		||||
        private int maxTotal = 5;
 | 
			
		||||
        private long maxWait = 5000;    // ms
 | 
			
		||||
 | 
			
		||||
        public String getPassword() {
 | 
			
		||||
            String password = this.password;
 | 
			
		||||
            try {
 | 
			
		||||
                password = EncryptUtils.desDecrypt(this.password);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            return password;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取刨除服务器文件主目录外的相对路径(用于FTP的相对路径)
 | 
			
		||||
     *
 | 
			
		||||
     * @param file
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public String getRelativePath(File file) {
 | 
			
		||||
        String mainPath = getPath().getPath();
 | 
			
		||||
        String ftpPath = getFtp().getMainPath();
 | 
			
		||||
        if (Objects.nonNull(file)) {
 | 
			
		||||
            if (file.getPath().contains(mainPath)) {
 | 
			
		||||
                int len = file.getPath().length() - file.getName().length();
 | 
			
		||||
                String result = file.getPath().substring(mainPath.length(), len);
 | 
			
		||||
                // 处理分割符
 | 
			
		||||
                return dealPath(result);
 | 
			
		||||
            } else if (file.getPath().contains(ftpPath)) {
 | 
			
		||||
                int len = file.getPath().length() - file.getName().length();
 | 
			
		||||
                String result = file.getPath().substring(ftpPath.length(), len);
 | 
			
		||||
                // 处理分割符
 | 
			
		||||
                return dealPath(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return file.getPath();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 处理文件路径分隔符
 | 
			
		||||
     *
 | 
			
		||||
     * @param path
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private String dealPath(String path) {
 | 
			
		||||
        String os = System.getProperty("os.name");
 | 
			
		||||
        if (os.toLowerCase().startsWith(ElConstant.WIN) && path.contains("\\")) {
 | 
			
		||||
            return path.replace("\\", "/");
 | 
			
		||||
        } else if (os.toLowerCase().startsWith(ElConstant.MAC)) {
 | 
			
		||||
            return path;
 | 
			
		||||
        }
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // endregion
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,149 @@
 | 
			
		|||
package me.zhengjie.utils.ftp;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import me.zhengjie.config.properties.FileProperties;
 | 
			
		||||
import org.apache.commons.net.ftp.FTP;
 | 
			
		||||
import org.apache.commons.net.ftp.FTPClient;
 | 
			
		||||
import org.apache.commons.pool2.BasePooledObjectFactory;
 | 
			
		||||
import org.apache.commons.pool2.PooledObject;
 | 
			
		||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
 | 
			
		||||
import org.apache.commons.pool2.impl.GenericObjectPool;
 | 
			
		||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * FTP连接池管理器
 | 
			
		||||
 *
 | 
			
		||||
 * @author pcshao.cn
 | 
			
		||||
 * @date 13/04/2024
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Service
 | 
			
		||||
public class FtpConnectionPoolManager {
 | 
			
		||||
 | 
			
		||||
    private volatile static GenericObjectPool<FTPClient> pool = null;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private FileProperties fileProperties;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化连接池
 | 
			
		||||
     */
 | 
			
		||||
    public void initPool() {
 | 
			
		||||
        if (Objects.nonNull(pool))
 | 
			
		||||
            return;
 | 
			
		||||
        else {
 | 
			
		||||
            // 懒加载
 | 
			
		||||
            synchronized (this) {
 | 
			
		||||
                if (Objects.nonNull(pool))
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        FileProperties.FtpConfig ftp = fileProperties.getFtp();
 | 
			
		||||
        GenericObjectPoolConfig<FTPClient> poolConfig = new GenericObjectPoolConfig<>();
 | 
			
		||||
        poolConfig.setMaxTotal(ftp.getMaxTotal()); // 设置连接池最大连接数
 | 
			
		||||
        poolConfig.setMaxIdle(ftp.getMaxIdle()); // 设置连接池最大空闲连接数
 | 
			
		||||
        poolConfig.setMinIdle(ftp.getMinIdle()); // 设置连接池最小空闲连接数
 | 
			
		||||
        poolConfig.setMaxWaitMillis(ftp.getMaxWait()); // 设置连接池最大等待时间,单位为毫秒
 | 
			
		||||
        poolConfig.setTestOnBorrow(true);   // 设置获取连接前进行检查
 | 
			
		||||
 | 
			
		||||
        pool = new GenericObjectPool<>(new BasePooledObjectFactory<FTPClient>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public FTPClient create() throws Exception {
 | 
			
		||||
                String server = ftp.getHost();
 | 
			
		||||
                int port = ftp.getPort();
 | 
			
		||||
                String username = ftp.getUsername();
 | 
			
		||||
                String password = ftp.getPassword();
 | 
			
		||||
                FTPClient ftpClient = new FTPClient();
 | 
			
		||||
                // 设置控制连接的字符编码为UTF-8
 | 
			
		||||
                ftpClient.setControlEncoding("UTF-8");
 | 
			
		||||
                ftpClient.connect(server, port);
 | 
			
		||||
                ftpClient.login(username, password);
 | 
			
		||||
                ftpClient.enterLocalPassiveMode();
 | 
			
		||||
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 | 
			
		||||
                ftpClient.setConnectTimeout(ftp.getConnectTimeout()); // 连接超时时间为5秒
 | 
			
		||||
                ftpClient.setDataTimeout(ftp.getDataTimeout()); // 数据传输超时时间为30秒
 | 
			
		||||
                return ftpClient;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void destroyObject(PooledObject<FTPClient> p) throws Exception {
 | 
			
		||||
                FTPClient ftpClient = p.getObject();
 | 
			
		||||
                ftpClient.logout();
 | 
			
		||||
                ftpClient.disconnect();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean validateObject(PooledObject<FTPClient> p) {
 | 
			
		||||
                FTPClient ftpClient = p.getObject();
 | 
			
		||||
                try {
 | 
			
		||||
                    log.warn("FTP连接池管理 检测FTP连接状态 reply:{} status:{} obj:{}", ftpClient.getReplyString(), ftpClient.getStatus(), ftpClient);
 | 
			
		||||
                    return ftpClient.isConnected() && ftpClient.sendNoOp();
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    log.warn("FTP连接池管理 检测FTP连接失败 {}", e.getMessage());
 | 
			
		||||
                    if (log.isDebugEnabled())
 | 
			
		||||
                        log.debug(e.getMessage(), e);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
 | 
			
		||||
                DefaultPooledObject defaultPooledObject = new DefaultPooledObject(ftpClient);
 | 
			
		||||
                return defaultPooledObject;
 | 
			
		||||
            }
 | 
			
		||||
        }, poolConfig);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 执行方法,包含获取和归还连接
 | 
			
		||||
     *
 | 
			
		||||
     * @param function
 | 
			
		||||
     * @param <R>
 | 
			
		||||
     * @return
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public <R> R execute(Function<FTPClient, R> function) throws Exception {
 | 
			
		||||
        FTPClient ftpClient = null;
 | 
			
		||||
        try {
 | 
			
		||||
            ftpClient = borrowFTPClient();
 | 
			
		||||
            return function.apply(ftpClient);
 | 
			
		||||
        } finally {
 | 
			
		||||
            returnFTPClient(ftpClient);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取一个连接
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     */
 | 
			
		||||
    public FTPClient borrowFTPClient() throws Exception {
 | 
			
		||||
        initPool();
 | 
			
		||||
        return pool.borrowObject();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 归还连接
 | 
			
		||||
     *
 | 
			
		||||
     * @param ftpClient
 | 
			
		||||
     */
 | 
			
		||||
    public void returnFTPClient(FTPClient ftpClient) {
 | 
			
		||||
        initPool();
 | 
			
		||||
        pool.returnObject(ftpClient);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 关闭连接池
 | 
			
		||||
     */
 | 
			
		||||
    public void close() {
 | 
			
		||||
        if (Objects.isNull(pool))
 | 
			
		||||
            return;
 | 
			
		||||
        pool.close();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,299 @@
 | 
			
		|||
package me.zhengjie.utils.ftp;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.commons.net.ftp.FTP;
 | 
			
		||||
import org.apache.commons.net.ftp.FTPClient;
 | 
			
		||||
import org.apache.commons.net.ftp.FTPFile;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author pcshao.cn
 | 
			
		||||
 * @date 20/01/2024
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class FtpUtil {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FTP文件上传
 | 
			
		||||
     *
 | 
			
		||||
     * @param ftpClient
 | 
			
		||||
     * @param localFilePath
 | 
			
		||||
     * @param remoteDirectory
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean uploadFile(FTPClient ftpClient, String localFilePath, String remoteDirectory) {
 | 
			
		||||
        boolean done = false;
 | 
			
		||||
        try {
 | 
			
		||||
            // 检查远程目录是否存在
 | 
			
		||||
            checkRemoteDir(ftpClient, remoteDirectory);
 | 
			
		||||
 | 
			
		||||
            // 设置远程目录的字符编码为UTF-8
 | 
			
		||||
            ftpClient.changeWorkingDirectory(new String(remoteDirectory.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
 | 
			
		||||
            File localFile = new File(localFilePath);
 | 
			
		||||
 | 
			
		||||
            FileInputStream inputStream = new FileInputStream(localFile);
 | 
			
		||||
 | 
			
		||||
            String remoteFilePath = remoteDirectory + localFile.getName();
 | 
			
		||||
 | 
			
		||||
            done = ftpClient.storeFile(remoteFilePath, inputStream);
 | 
			
		||||
 | 
			
		||||
            if (done) {
 | 
			
		||||
                log.info("FtpUtil uploadFile successfully.");
 | 
			
		||||
            } else {
 | 
			
		||||
                log.error("FtpUtil uploadFile failed. reply: {} remotePath: {} obj: {}", ftpClient.getReplyString(), remoteFilePath, ftpClient);
 | 
			
		||||
            }
 | 
			
		||||
            inputStream.close();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
        return done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FTP文件上传
 | 
			
		||||
     *
 | 
			
		||||
     * @param server
 | 
			
		||||
     * @param port
 | 
			
		||||
     * @param username
 | 
			
		||||
     * @param password
 | 
			
		||||
     * @param localFilePath
 | 
			
		||||
     * @param remoteDirectory
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean uploadFile(String server, int port, String username, String password, String localFilePath, String remoteDirectory) {
 | 
			
		||||
        boolean done = false;
 | 
			
		||||
        FTPClient ftpClient = new FTPClient();
 | 
			
		||||
        try {
 | 
			
		||||
            // 设置控制连接的字符编码为UTF-8
 | 
			
		||||
            ftpClient.setControlEncoding("UTF-8");
 | 
			
		||||
            ftpClient.connect(server, port);
 | 
			
		||||
            ftpClient.login(username, password);
 | 
			
		||||
            ftpClient.enterLocalPassiveMode();
 | 
			
		||||
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 | 
			
		||||
 | 
			
		||||
            // 检查远程目录是否存在
 | 
			
		||||
            checkRemoteDir(ftpClient, remoteDirectory);
 | 
			
		||||
 | 
			
		||||
            // 设置远程目录的字符编码为UTF-8
 | 
			
		||||
            ftpClient.changeWorkingDirectory(new String(remoteDirectory.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
 | 
			
		||||
            File localFile = new File(localFilePath);
 | 
			
		||||
 | 
			
		||||
            FileInputStream inputStream = new FileInputStream(localFile);
 | 
			
		||||
 | 
			
		||||
            String remoteFilePath = remoteDirectory + localFile.getName();
 | 
			
		||||
 | 
			
		||||
            done = ftpClient.storeFile(remoteFilePath, inputStream);
 | 
			
		||||
 | 
			
		||||
            if (done) {
 | 
			
		||||
                log.info("FtpUtil uploadFile successfully.");
 | 
			
		||||
            } else {
 | 
			
		||||
                log.info("FtpUtil uploadFile failed. reply: {} remotePath: {}", ftpClient.getReplyString(), remoteFilePath);
 | 
			
		||||
            }
 | 
			
		||||
            inputStream.close();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
        } finally {
 | 
			
		||||
            try {
 | 
			
		||||
                if (ftpClient.isConnected()) {
 | 
			
		||||
                    ftpClient.logout();
 | 
			
		||||
                    ftpClient.disconnect();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                log.error(e.getMessage(), e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return done;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 检查远程目录,如果不存在则创建
 | 
			
		||||
     *
 | 
			
		||||
     * @param ftpClient
 | 
			
		||||
     * @param remoteDirectory
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     */
 | 
			
		||||
    private static void checkRemoteDir(FTPClient ftpClient, String remoteDirectory) throws IOException {
 | 
			
		||||
        FTPFile[] ftpFiles = ftpClient.mlistDir(remoteDirectory);
 | 
			
		||||
        log.info("FtpUtil mlistDir {} reply: {}", remoteDirectory, ftpClient.getReplyString());
 | 
			
		||||
        if (ftpFiles.length <= 0) {
 | 
			
		||||
            ftpClient.makeDirectory(remoteDirectory);
 | 
			
		||||
            log.info("FtpUtil makeDirectory {} reply: {}", remoteDirectory, ftpClient.getReplyString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FTP文件下载
 | 
			
		||||
     *
 | 
			
		||||
     * @param ftpClient
 | 
			
		||||
     * @param remoteFilePath
 | 
			
		||||
     * @param localDirectory
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static File downloadFile(FTPClient ftpClient, String remoteFilePath, String localDirectory) {
 | 
			
		||||
        File localFile = null;
 | 
			
		||||
        try {
 | 
			
		||||
            // 设置远程目录的字符编码为UTF-8
 | 
			
		||||
            String remoteDirectory = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
            ftpClient.changeWorkingDirectory(new String(remoteDirectory.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
 | 
			
		||||
            String remoteFileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
            localFile = new File(localDirectory + remoteFileName);
 | 
			
		||||
 | 
			
		||||
            OutputStream outputStream = new FileOutputStream(localFile);
 | 
			
		||||
 | 
			
		||||
            boolean success = ftpClient.retrieveFile(remoteFilePath, outputStream);
 | 
			
		||||
 | 
			
		||||
            if (success) {
 | 
			
		||||
                log.info("FtpUtil downloaded successfully.");
 | 
			
		||||
            } else {
 | 
			
		||||
                log.info("FtpUtil download failed. reply: {} remotePath: {}", ftpClient.getReplyString(), remoteFilePath);
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            outputStream.close();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return localFile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FTP文件下载
 | 
			
		||||
     *
 | 
			
		||||
     * @param server
 | 
			
		||||
     * @param port
 | 
			
		||||
     * @param username
 | 
			
		||||
     * @param password
 | 
			
		||||
     * @param remoteFilePath
 | 
			
		||||
     * @param localDirectory
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static File downloadFile(String server, int port, String username, String password, String remoteFilePath, String localDirectory) {
 | 
			
		||||
        File localFile = null;
 | 
			
		||||
        FTPClient ftpClient = new FTPClient();
 | 
			
		||||
        try {
 | 
			
		||||
            // 设置控制连接的字符编码为UTF-8
 | 
			
		||||
            ftpClient.setControlEncoding("UTF-8");
 | 
			
		||||
            ftpClient.connect(server, port);
 | 
			
		||||
            ftpClient.login(username, password);
 | 
			
		||||
            ftpClient.enterLocalPassiveMode();
 | 
			
		||||
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 | 
			
		||||
 | 
			
		||||
            // 设置远程目录的字符编码为UTF-8
 | 
			
		||||
            String remoteDirectory = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
            ftpClient.changeWorkingDirectory(new String(remoteDirectory.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
 | 
			
		||||
            String remoteFileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
            localFile = new File(localDirectory + remoteFileName);
 | 
			
		||||
 | 
			
		||||
            OutputStream outputStream = new FileOutputStream(localFile);
 | 
			
		||||
 | 
			
		||||
            boolean success = ftpClient.retrieveFile(remoteFilePath, outputStream);
 | 
			
		||||
 | 
			
		||||
            if (success) {
 | 
			
		||||
                log.info("FtpUtil downloaded successfully.");
 | 
			
		||||
            } else {
 | 
			
		||||
                log.info("FtpUtil download failed. reply: {} remotePath: {}", ftpClient.getReplyString(), remoteFilePath);
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            outputStream.close();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
            return null;
 | 
			
		||||
        } finally {
 | 
			
		||||
            try {
 | 
			
		||||
                if (ftpClient.isConnected()) {
 | 
			
		||||
                    ftpClient.logout();
 | 
			
		||||
                    ftpClient.disconnect();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                log.error(e.getMessage(), e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return localFile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FTP文件删除
 | 
			
		||||
     *
 | 
			
		||||
     * @param ftpClient
 | 
			
		||||
     * @param remoteFilePath
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean deleteFile(FTPClient ftpClient, String remoteFilePath) {
 | 
			
		||||
        boolean success = false;
 | 
			
		||||
        try {
 | 
			
		||||
            // 设置远程目录的字符编码为UTF-8
 | 
			
		||||
            String remoteDirectory = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
            ftpClient.changeWorkingDirectory(new String(remoteDirectory.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
 | 
			
		||||
            String remoteFileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
 | 
			
		||||
            success = ftpClient.deleteFile(remoteFileName);
 | 
			
		||||
 | 
			
		||||
            if (success) {
 | 
			
		||||
                log.info("FtpUtil delete successfully.");
 | 
			
		||||
            } else {
 | 
			
		||||
                log.info("FtpUtil delete failed. reply: {} remotePath: {}", ftpClient.getReplyString(), remoteFilePath);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
        return success;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FTP文件删除
 | 
			
		||||
     *
 | 
			
		||||
     * @param server
 | 
			
		||||
     * @param port
 | 
			
		||||
     * @param username
 | 
			
		||||
     * @param password
 | 
			
		||||
     * @param remoteFilePath
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean deleteFile(String server, int port, String username, String password, String remoteFilePath) {
 | 
			
		||||
        boolean success = false;
 | 
			
		||||
        FTPClient ftpClient = new FTPClient();
 | 
			
		||||
        try {
 | 
			
		||||
            // 设置控制连接的字符编码为UTF-8
 | 
			
		||||
            ftpClient.setControlEncoding("UTF-8");
 | 
			
		||||
            ftpClient.connect(server, port);
 | 
			
		||||
            ftpClient.login(username, password);
 | 
			
		||||
            ftpClient.enterLocalPassiveMode();
 | 
			
		||||
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 | 
			
		||||
 | 
			
		||||
            // 设置远程目录的字符编码为UTF-8
 | 
			
		||||
            String remoteDirectory = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
            ftpClient.changeWorkingDirectory(new String(remoteDirectory.getBytes(StandardCharsets.UTF_8)));
 | 
			
		||||
 | 
			
		||||
            String remoteFileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1);
 | 
			
		||||
 | 
			
		||||
            success = ftpClient.deleteFile(remoteFileName);
 | 
			
		||||
 | 
			
		||||
            if (success) {
 | 
			
		||||
                log.info("FtpUtil delete successfully.");
 | 
			
		||||
            } else {
 | 
			
		||||
                log.info("FtpUtil delete failed. reply: {} remotePath: {}", ftpClient.getReplyString(), remoteFilePath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error(e.getMessage(), e);
 | 
			
		||||
        } finally {
 | 
			
		||||
            try {
 | 
			
		||||
                if (ftpClient.isConnected()) {
 | 
			
		||||
                    ftpClient.logout();
 | 
			
		||||
                    ftpClient.disconnect();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                log.error(e.getMessage(), e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return success;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
package me.zhengjie.utils;
 | 
			
		||||
 | 
			
		||||
import me.zhengjie.utils.ftp.FtpUtil;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author pcshao.cn
 | 
			
		||||
 * @date 2025/3/12
 | 
			
		||||
 */
 | 
			
		||||
public class FtpUtilTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testDowndload() throws Exception {
 | 
			
		||||
        String password = EncryptUtils.desDecrypt("xxx");
 | 
			
		||||
        FtpUtil.downloadFile("ftp.xxx.xx", 21, "ftptest", password,
 | 
			
		||||
                "/test.xlsx", "tempFile" + System.currentTimeMillis() + ".xlsx");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void testUpload() throws Exception {
 | 
			
		||||
        String password = EncryptUtils.desDecrypt("xxx");
 | 
			
		||||
        FtpUtil.uploadFile("ftp.xxx.xx", 21, "ftptest", password, "tempFile", "");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -116,3 +116,17 @@ file:
 | 
			
		|||
  # 文件大小 /M
 | 
			
		||||
  maxSize: 100
 | 
			
		||||
  avatarMaxSize: 5
 | 
			
		||||
  # FTP文件服务器配置
 | 
			
		||||
  ftp:
 | 
			
		||||
    mainPath: \home\eladmin\file\
 | 
			
		||||
    username: ftptest
 | 
			
		||||
    password: B6890183857ABC452C9E3170906AF9AB97872252D8A4769E
 | 
			
		||||
    host: pcshao.cn
 | 
			
		||||
    port: 21
 | 
			
		||||
    connectTimeout: 5000 # 连接超时时间 ms
 | 
			
		||||
    dataTimeout: 30000 # 数据传输超时时间 ms
 | 
			
		||||
    # FTP线程池
 | 
			
		||||
    minIdle: 1
 | 
			
		||||
    maxIdle: 3
 | 
			
		||||
    maxTotal: 5
 | 
			
		||||
    maxWait: 5000 # ms
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,3 +127,17 @@ file:
 | 
			
		|||
  # 文件大小 /M
 | 
			
		||||
  maxSize: 100
 | 
			
		||||
  avatarMaxSize: 5
 | 
			
		||||
  # FTP文件服务器配置
 | 
			
		||||
  ftp:
 | 
			
		||||
    mainPath: \home\eladmin\file\
 | 
			
		||||
    username: ftptest
 | 
			
		||||
    password: B6890183857ABC452C9E3170906AF9AB97872252D8A4769E
 | 
			
		||||
    host: pcshao.cn
 | 
			
		||||
    port: 21
 | 
			
		||||
    connectTimeout: 5000 # 连接超时时间 ms
 | 
			
		||||
    dataTimeout: 30000 # 数据传输超时时间 ms
 | 
			
		||||
    # FTP线程池
 | 
			
		||||
    minIdle: 1
 | 
			
		||||
    maxIdle: 3
 | 
			
		||||
    maxTotal: 5
 | 
			
		||||
    maxWait: 5000 # ms
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue