java实现ftp上传

java  maven 实现 ftp 上传

pom.xml

    <!-- Apache Commons Net 用于 FTP 操作 -->
    <dependency>
      <groupId>commons-net</groupId>
      <artifactId>commons-net</artifactId>
      <version>3.9.0</version>
    </dependency>

FtpUploader.java

package com.JoinCallCCVoxGuide;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
 

public class FtpUploader {
    protected static final Logger logger = LoggerFactory.getLogger(FtpUploader.class);

    private String server;
    private int port;
    private String username;
    private String password;
    private FTPClient ftpClient;

    /**
     * 构造函数
     * @param server FTP服务器地址
     * @param port FTP端口(默认21)
     * @param username 用户名
     * @param password 密码
     */
    public FtpUploader(String server, int port, String username, String password) {
        this.server = cleanServerAddress(server);  // 清理地址
        this.port = port;
        this.username = username;
        this.password = password;
        this.ftpClient = new FTPClient();
    }

    /**
     * 清理FTP服务器地址
     * 移除 ftp://, ftps:// 等协议前缀
     */
    private String cleanServerAddress(String server) {
        if (server == null || server.isEmpty()) {
            return server;
        }

        // 转换为小写,统一处理
        String cleaned = server.toLowerCase();

        // 移除协议前缀
        if (cleaned.startsWith("ftp://")) {
            cleaned = cleaned.substring(6);
        } else if (cleaned.startsWith("ftps://")) {
            cleaned = cleaned.substring(7);
        }

        // 如果还有端口号在地址中(如 ftp://192.168.1.150:21),需要分离
        // 但通常FTPClient的connect方法会单独处理端口
        // 这里只移除协议头,端口由另一个参数指定

        return cleaned.trim();
    }


    public FtpUploader(String server, String username, String password) {
        this(server, 21, username, password);
    }

    /**
     * 连接FTP服务器
     * @return 连接是否成功
     * @throws IOException
     */
    public boolean connect() throws IOException {
        ftpClient.connect(server, port);
        int replyCode = ftpClient.getReplyCode();

        if (!FTPReply.isPositiveCompletion(replyCode)) {
            ftpClient.disconnect();
            logger.error("FTP服务器拒绝连接,回复码: {}", replyCode);
            return false;
        }

        boolean loginSuccess = ftpClient.login(username, password);
        if (!loginSuccess) {
            logger.error("FTP登录失败,用户名或密码错误");
            return false;
        }

        // 设置被动模式(适合大多数防火墙)
        ftpClient.enterLocalPassiveMode();

        // 设置文件传输类型为二进制
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

        logger.info("成功连接到FTP服务器: {}:{}", server, port);
        return true;
    }

    /**
     * 上传文件
     * @param localFilePath 本地文件路径
     * @param remoteFilePath 远程文件路径
     * @return 上传是否成功
     * @throws IOException
     */
    public boolean uploadFile(String localFilePath, String remoteFilePath) throws IOException {
        File localFile = new File(localFilePath);

        if (!localFile.exists()) {
            logger.error("本地文件不存在: {}", localFilePath);
            return false;
        }

        // 如果远程目录不存在,创建目录
        String remoteDir = getRemoteDirectory(remoteFilePath);
        if (remoteDir != null && !remoteDir.isEmpty()) {
            createRemoteDirectory(remoteDir);
        }

        try (InputStream inputStream = new FileInputStream(localFile)) {
            boolean success = ftpClient.storeFile(remoteFilePath, inputStream);
            if (success) {
                logger.info("文件上传成功: {} -> {}", localFilePath, remoteFilePath);
            } else {
                logger.error("文件上传失败: {}", localFilePath);
            }
            return success;
        }
    }

    /**
     * 上传整个目录
     * @param localDirPath 本地目录路径
     * @param remoteDirPath 远程目录路径
     * @return 上传是否成功
     * @throws IOException
     */
    public boolean uploadDirectory(String localDirPath, String remoteDirPath) throws IOException {
        File localDir = new File(localDirPath);

        if (!localDir.exists() || !localDir.isDirectory()) {
            logger.error("本地目录不存在或不是目录: {}", localDirPath);
            return false;
        }

        // 创建远程目录
        createRemoteDirectory(remoteDirPath);

        File[] files = localDir.listFiles();
        if (files == null) {
            return true;
        }

        boolean allSuccess = true;
        for (File file : files) {
            String remoteFilePath = remoteDirPath + "/" + file.getName();

            if (file.isDirectory()) {
                // 递归上传子目录
                allSuccess &= uploadDirectory(file.getAbsolutePath(), remoteFilePath);
            } else {
                // 上传文件
                allSuccess &= uploadFile(file.getAbsolutePath(), remoteFilePath);
            }
        }

        return allSuccess;
    }

    /**
     * 创建远程目录(支持多级目录创建)
     * @param remoteDirPath 远程目录路径
     * @return 创建是否成功
     * @throws IOException
     */
    private boolean createRemoteDirectory(String remoteDirPath) throws IOException {
        // 分隔符标准化
        remoteDirPath = remoteDirPath.replace("\\", "/");

        String[] directories = remoteDirPath.split("/");
        StringBuilder currentPath = new StringBuilder();

        for (String dir : directories) {
            if (dir.isEmpty()) continue;

            currentPath.append("/").append(dir);
            String path = currentPath.toString();

            // 检查目录是否存在,不存在则创建
            if (!ftpClient.changeWorkingDirectory(path)) {
                boolean success = ftpClient.makeDirectory(path);
                if (success) {
                    logger.debug("创建远程目录: {}", path);
                } else {
                    logger.error("创建远程目录失败: {}", path);
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * 从文件路径中提取目录部分
     * @param filePath 文件路径
     * @return 目录路径
     */
    private String getRemoteDirectory(String filePath) {
        int lastSlash = filePath.lastIndexOf('/');
        if (lastSlash > 0) {
            return filePath.substring(0, lastSlash);
        }
        return "";
    }

    /**
     * 断开FTP连接
     */
    public void disconnect() {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
                logger.info("FTP连接已关闭");
            } catch (IOException e) {
                logger.error("关闭FTP连接时出错", e);
            }
        }
    }

    /**
     * 设置连接超时时间(毫秒)
     * @param timeout 超时时间
     */
    public void setTimeout(int timeout) {
        ftpClient.setConnectTimeout(timeout);
        ftpClient.setDefaultTimeout(timeout);
        ftpClient.setDataTimeout(timeout);
    }

    /**
     * 检查FTP服务器是否可连接
     * @return 是否可连接
     */
    public boolean isConnected() {
        return ftpClient.isConnected();
    }
}

App.java

package com.JoinCallCCVoxGuide;


/**
 * Hello world!
 */
public class App {
    protected static final Logger logger = LoggerFactory.getLogger(App.class);

    public static void main(String[] args) {
        //System.out.println("Hello World!");
 
        // 配置FTP连接参数
        String server = "ftp://192.168.1.150";
        int port =  21;
        String username = "support";
        String password =  "12345678";
        //远程路径
        String remoteFilePath =  "/ysapps/pbxcenter/var/lib/asterisk/sounds/record/NULL.wav";
        //本地文件
        String localFilePath = "d:\\JoinCallCCWav\\";

        localFilePath=localFilePath+"DHCD.wav";

        // 创建上传器实例
        FtpUploader uploader = new FtpUploader(server, port, username, password);

        try {
            // 1. 连接FTP服务器
            if (!uploader.connect()) {
                System.err.println("连接FTP服务器失败");
                return;
            }

            // 2. 设置超时时间(可选)
            uploader.setTimeout(30000);

            // 3. 上传单个文件
            boolean success = uploader.uploadFile(localFilePath, remoteFilePath);
            if (success) {
                System.out.println("文件上传成功");
            }

            // 4. 上传整个目录(可选)
            //String localDir = "/path/to/local/directory";
            //String remoteDir = "/upload/directory";
            //success = uploader.uploadDirectory(localDir, remoteDir);
            //if (success) {
            //    System.out.println("目录上传成功");
            //}

            // 5. 使用FTPS(安全FTP)示例
            //useFtpsExample();

        } catch (Exception e) {
            System.err.println("FTP操作出错: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 确保断开连接
            uploader.disconnect();
        }
    }
 


}

 

posted @ 2026-01-13 11:37  海乐学习  阅读(3)  评论(0)    收藏  举报