java:ftp文件处理相关功能,独立ftplient的创建

 

以下是一种可能的优化方式,将 FTPClient 的创建和管理放在一个单独的类中,通过依赖注入的方式提供给控制器使用:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/ftp")
public class FtpFileTransferController {

    private static final Logger LOGGER = LoggerFactory.getLogger(FtpFileTransferController.class);

    private FtpClientManager ftpClientManager;

    public FtpFileTransferController(FtpClientManager ftpClientManager) {
        this.ftpClientManager = ftpClientManager;
    }

    @PostMapping("/login")
    public ResponseEntity loginToFtp(String server, int port, String user, String pass) {
        boolean success = ftpClientManager.login(server, port, user, pass);
        if (success) {
            LOGGER.info("用户 {} 登录 FTP 服务器", user);
            return new ResponseEntity<>(true, HttpStatus.OK);
        } else {
            LOGGER.error("用户 {} 连接或登录 FTP 服务器时出现错误", user);
            return new ResponseEntity<>(false, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PostMapping("/download")
    public ResponseEntity downloadFile(String remotePath, String localPath, String operator) {
        FTPClient ftpClient = ftpClientManager.getFtpClient();
        if (ftpClient!= null) {
            try {
                FTPFile[] files = ftpClient.listFiles(remotePath);
                if (files.length > 0) {
                    FTPFile file = files[0];
                    String originalFileName = file.getName();
                    File localFile = getUniqueLocalFile(originalFileName, localPath);
                    OutputStream outputStream = new FileOutputStream(localFile);
                    try {
                        ftpClient.retrieveFile(remotePath, outputStream);
                        LOGGER.info("用户 {} 下载文件 {}", operator, remotePath);
                        return new ResponseEntity<>("下载成功", HttpStatus.OK);
                    } catch (IOException e) {
                        LOGGER.error("用户 {} 下载文件 {} 时出现错误: {}", operator, remotePath, e.getMessage());
                        return new ResponseEntity<>("下载失败", HttpStatus.INTERNAL_SERVER_ERROR);
                    } finally {
                        try {
                            outputStream.close();
                        } catch (IOException e) {
                            LOGGER.error("用户 {} 关闭输出流时出现错误: {}", operator, e.getMessage());
                        }
                    }
                }
                LOGGER.warn("用户 {} 尝试下载文件,但远程路径 {} 下无文件可下载", operator, remotePath);
                return new ResponseEntity<>("远程路径下无文件可下载", HttpStatus.NOT_FOUND);
            } catch (IOException e) {
                LOGGER.error("用户 {} 下载文件操作时出现错误: {}", operator, e.getMessage());
                return new ResponseEntity<>("下载失败", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else {
            LOGGER.error("未获取到有效的 FTP 客户端连接");
            return new ResponseEntity<>("获取 FTP 客户端连接失败", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    // 其他方法类似修改,从 FtpClientManager 获取 FTPClient 对象

    @PostMapping("/createFolder")
    public ResponseEntity createFolder(String folderPath, String operator) {
        FTPClient ftpClient = ftpClientManager.getFtpClient();
        if (ftpClient!= null) {
            try {
                boolean created = ftpClient.makeDirectory(folderPath);
                if (created) {
                    LOGGER.info("用户 {} 创建文件夹 {}", operator, folderPath);
                    return new ResponseEntity<>("文件夹创建成功", HttpStatus.OK);
                } else {
                    LOGGER.error("用户 {} 创建文件夹 {} 失败", operator, folderPath);
                    return new ResponseEntity<>("创建文件夹失败", HttpStatus.INTERNAL_SERVER_ERROR);
                }
            } catch (IOException e) {
                LOGGER.error("用户 {} 创建文件夹 {} 时出现错误: {}", operator, folderPath, e.getMessage());
                return new ResponseEntity<>("创建文件夹失败", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else {
            LOGGER.error("未获取到有效的 FTP 客户端连接");
            return new ResponseEntity<>("获取 FTP 客户端连接失败", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    // 省略其他方法,修改方式类似

    // 检查服务器端指定路径是否存在文件
    public static boolean checkFileExists(FTPClient ftpClient, String filePath) throws IOException {
        try {
            FTPFile[] files = ftpClient.listFiles(filePath);
            return files.length > 0;
        } catch (IOException e) {
            LOGGER.error("检查服务器端文件存在性时出现错误: {}", e.getMessage());
            throw e;
        }
    }

    // 给文件名添加数字后缀以避免冲突(服务器端)
    public static String getUniqueRemoteFileName(String originalFileName, String remotePath, FTPClient ftpClient) {
        int count = 1;
        String newFileName = originalFileName;
        while (checkFileExists(ftpClient, remotePath + File.separator + newFileName)) {
            newFileName = getFileNameWithSuffix(originalFileName, count++);
        }
        return newFileName;
    }

    // 给文件名添加数字后缀以避免冲突(本地端)
    public static File getUniqueLocalFile(String originalFileName, String localPath) {
        int count = 1;
        String newFileName = originalFileName;
        File file = new File(localPath + File.separator + newFileName);
        while (file.exists()) {
            newFileName = getFileNameWithSuffix(originalFileName, count++);
            file = new File(localPath + File.separator + newFileName);
        }
        return file;
    }

    // 获取带有数字后缀的文件名
    public static String getFileNameWithSuffix(String originalFileName, int count) {
        String fileNameWithoutExtension = originalFileName.substring(0, originalFileName.lastIndexOf('.'));
        String fileExtension = originalFileName.substring(originalFileName.lastIndexOf('.'));
        return fileNameWithoutExtension + "_" + count + fileExtension;
    }

    @PostMapping("/renameFolder")
    public ResponseEntity renameFolder(String oldFolderPath, String newFolderPath) {
        FTPClient ftpClient = ftpClientManager.getFtpClient();
        if (ftpClient!= null) {
            try {
                boolean renamed = ftpClient.rename(oldFolderPath, newFolderPath);
                if (renamed) {
                    LOGGER.info("文件夹重命名成功,旧路径: {},新路径: {}", oldFolderPath, newFolderPath);
                    return new ResponseEntity<>("文件夹重命名成功", HttpStatus.OK);
                } else {
                    LOGGER.error("文件夹重命名失败,旧路径: {},新路径: {}", oldFolderPath, newFolderPath);
                    return new ResponseEntity<>("文件夹重命名失败", HttpStatus.INTERNAL_SERVER_ERROR);
                }
            } catch (IOException e) {
                LOGGER.error("文件夹重命名时出现错误: {}", e.getMessage());
                return new ResponseEntity<>("文件夹重命名失败", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else {
            LOGGER.error("未获取到有效的 FTP 客户端连接");
            return new ResponseEntity<>("获取 FTP 客户端连接失败", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

class FtpClientManager {

    private FTPClient ftpClient;

    public boolean login(String server, int port, String user, String pass) {
        ftpClient = new FTPClient();
        try {
            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
            ftpClient.enterLocalPassiveMode();
            return true;
        } catch (IOException e) {
            LOGGER.error("连接或登录 FTP 服务器时出现错误: {}", e.getMessage());
            return false;
        }
    }

    public FTPClient getFtpClient() {
        return ftpClient;
    }
}

这样,在控制器的方法中,通过调用 FtpClientManager 的方法来获取有效的 FTPClient 对象,而不是直接传递它。

 

你可能感兴趣的:(java)