上传文件到FTP服务器,工具类

上传文件到FTP服务器,工具类

一、工具类

package com.zyf.study_fileupload.controller;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.util.TimeZone;
import java.util.logging.Logger;

public class FtpUtil {

    private FTPClient ftpClient;

    private String strIp;  // 服务器IP地址
    private int intPort;  // FTP服务器端口号
    private String username;  // 用户名
    private String password;  // 密码

    private static Logger logger = Logger.getLogger(FtpUtil.class.getName());

    // FtpClient的Set和Get函数
    public FTPClient getFtpClient() {
        return ftpClient;
    }
    public void setFtpClient(FTPClient ftpClient) {
        this.ftpClient = ftpClient;
    }

    /**
     * Ftp构造函数
     * 用于创建FTPClient对象,并封装连接FTP所需信息
     */
    public FtpUtil(String strIp, int intPort, String username, String password) {
        this.strIp = strIp;
        this.intPort = intPort;
        this.username = username;
        this.password = password;
        this.ftpClient = new FTPClient();
    }

    /**
     * 与FTP服务器建立连接
     */
    public boolean ftpConnect() throws IOException {
        boolean isLogin = false;
        FTPClientConfig ftpClientConfig = new FTPClientConfig();
        ftpClientConfig.setServerTimeZoneId(TimeZone.getDefault().getID());
        this.ftpClient.setControlEncoding("utf-8");
        this.ftpClient.enterLocalPassiveMode();
        this.ftpClient.configure(ftpClientConfig);

        try {
            if (this.intPort > 0) {
                this.ftpClient.connect(this.strIp,this.intPort);
            } else {
                this.ftpClient.connect(this.strIp);
            }
            // FTP服务器连接回答
            int reply = this.ftpClient.getReplyCode();

            if (!FTPReply.isPositiveCompletion(reply)) {
                this.ftpClient.disconnect();
                logger.info("登录FTP服务失败");
                return false;
            }

            if (!ftpClient.login(this.username,this.password)) {
                this.ftpClient.disconnect();
                logger.info("登陆失败,用户名或密码错误!");
                return false;
            }

            // 设置传输协议
            this.ftpClient.enterLocalPassiveMode();
            this.ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            logger.info("恭喜"+this.username+"成功登陆FTP服务器");
            isLogin = true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(this.username+"登录FTP服务失败"+e.getMessage());
        }
        this.ftpClient.setBufferSize(1024*2);
        this.ftpClient.setDataTimeout(30 * 1000);
        return isLogin;
    }

    /**
     * 关闭FTP服务器连接
     */
    public void ftpDisConnect() {
        if (null != this.ftpClient && this.ftpClient.isConnected()) {
            try {
                boolean result = this.ftpClient.logout();  // 退出FTP服务器
                if (result) {
                    logger.info("成功退出服务器");
                }
            } catch (IOException e) {
                e.printStackTrace();
                logger.warning("退出FTP服务器异常"+e.getMessage());
            } finally {
                try {
                    this.ftpClient.disconnect(); // 关闭FTP服务器的连接
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.warning("关闭FTP服务器异常!!");
                }
            }
        }
    }

    /**
     * 上传文件到FTP服务器
     * @param localFile  本地文件(前端发送)
     * @param romotUpLoadPath 上传服务器路径(为空则为FTP服务器根目录)
     * @return boolean  (当返回值为true时,将文件上传路径、文件名存入数据库)
     */
    public boolean uploadFile(File localFile,String romotUpLoadPath) {
        BufferedInputStream inStream = null;
        try {
            this.ftpClient.changeWorkingDirectory(romotUpLoadPath); // 改变工作路径(为空则为切换为FTP服务器根路径)

            inStream = new BufferedInputStream(new FileInputStream(localFile));  // 将本地(传入)文件转化为输入流

            logger.info(localFile.getName()+"开始上传...");

            boolean success = this.ftpClient.storeFile(localFile.getName(),inStream); // 上传文件(记得开放端口)返回true/false

            if (success) {
                logger.info(localFile.getName()+"上传成功");
                return true;
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            logger.info(localFile+"未找到");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }


    /**
     * 下载文件
     * @param remoteFileName    待下载文件名称(通过数据库字段或存放路径获取)
     * @param localDires    下载到本地的路径(前端选择下载路径)
     * @param remoteDownLoadPath    remoteFileName所在的路径(通过数据库存放路径获取)
     * @return
     */
    public boolean downloadFile(String remoteFileName,String localDires,String remoteDownLoadPath) {
        String strFilePath = localDires + "\\" + remoteFileName;
        BufferedOutputStream outStream = null;
        boolean success = false;

        try {
            this.ftpClient.changeWorkingDirectory(remoteDownLoadPath); // changeWorkingDirectory()路径切换方法

            outStream = new BufferedOutputStream(new FileOutputStream(strFilePath));  // 将文件转化为输出流
            logger.info(remoteFileName+"开始下载...");
            success = this.ftpClient.retrieveFile(remoteFileName,outStream);

            if (success == true) {
                logger.info(remoteFileName + "成功下载到" + strFilePath);
                return success;
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.info(remoteFileName+"下载失败");
        } finally {
            if (null != outStream) {
                try {
                    outStream.flush();
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if (success == false) {
            logger.info(remoteFileName+"下载失败!!!");
        }
        return success;
    }


    /**
     * 上传文件夹(文件夹名称不能相同)
     * @param localDirectory    本地文件夹
     * @param remoteDirectoryPath   FTP服务器路径
     * @return
     */
    public boolean uploadDirectory(String localDirectory,String remoteDirectoryPath) {
        File src = new File(localDirectory);
        try {
            remoteDirectoryPath = remoteDirectoryPath + "/" + src.getName();
            boolean bool = this.ftpClient.makeDirectory(remoteDirectoryPath);  // 创建目录
            if (!bool) {
                logger.info("创建"+remoteDirectoryPath+"目录失败");
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info(remoteDirectoryPath+"目录创建失败");
        }
        // 创建成功,扫描文件夹中的文件
        File[] allFile = src.listFiles();  // 创建文件数组

        for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
            if (!allFile[currentFile].isDirectory()) {  // 判断当前元素不是文件夹
                String srcName = allFile[currentFile].getPath();
                uploadFile(new File(srcName),remoteDirectoryPath);  // 调用上传文件方法,将文件夹中的文件上传
            }
        }

        for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
            if (allFile[currentFile].isDirectory()) {  // 判断当前元素是文件夹
                // 递归,调用上传文件夹方法(实现多级文件夹上传)
                uploadDirectory(allFile[currentFile].getPath(),remoteDirectoryPath);
            }
        }
        return true;
    }


    /**
     * 下载文件夹
     * @param localDirectoryPath
     * @param remoteDirectory   远程文件夹
     * @return
     */
    private String strFileName = "/";
    public boolean downLoadDirectory(String localDirectoryPath,String remoteDirectory) {
        try {

            String fileName = new File(remoteDirectory).getName();
            strFileName = strFileName + fileName + "/";
            localDirectoryPath = localDirectoryPath + "\\" + fileName;

            new File(localDirectoryPath).mkdirs();  // 在本地创建目录

            this.ftpClient.enterLocalPassiveMode(); // 使用被动模式设为默认

            FTPFile[] allFile = this.ftpClient.listFiles(strFileName);  // 获取远程文件夹中的所有子元素(包含.和..文件夹)

            for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
                if (allFile[currentFile].isFile()) {  // 判断是文件
                    // 调用下载文件方法
                    downloadFile(allFile[currentFile].getName(),localDirectoryPath,remoteDirectory);
                }
            }

            for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
                if (allFile[currentFile].isDirectory()) {  // 判断是文件夹
                    if (allFile[currentFile].getName().equals(".") || allFile[currentFile].getName().equals("..")) {
                        // 如果文件夹名称是 . 或者 .. 都不下载
                        continue;
                    }
                    String strRemoteDirectoryPath = remoteDirectory + "/" + allFile[currentFile].getName();
                    // 递归,调用下载文件夹方法
                    downLoadDirectory(localDirectoryPath,strRemoteDirectoryPath);
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
            logger.info("下载文件夹失败");
            return false;
        }
        return true;
    }
}

二、测试类

package com.zyf.study_fileupload.controller;

import java.io.File;
import java.io.IOException;

public class FtpUtilTest {
    public static void main(String[] args) throws IOException {
        // 创建一个Ftp对象
        FtpUtil ftp = new FtpUtil("43.142.67.126",21,"user","123456");

        // 连接FTP服务器
        ftp.ftpConnect();

        // 上传文件
        ftp.uploadFile(new File("F:\\test\\file\\GIF.jpg"),"/upload");

        // 下载文件
        ftp.downloadFile("NYY.webp","F:\\test\\download","");

        // 上传文件夹(默认从FTP根路径开始)
        ftp.uploadDirectory("F:\\test\\upload","");

        // 下载文件夹
        ftp.downLoadDirectory("F:\\test\\download","/www/wwwroot/zyf/upload");

        // 关闭连接
        ftp.ftpDisConnect();
    }
}

注意:在Linux搭建的服务器上,从FTP下载文件夹时,通过ftpClient.listFiles(path);方法获取该目录下的所有元素(文件和文件夹)时,会自带名为 ‘.’ 和 ‘. .’ 两个文件夹,在下载文件夹时需要过滤掉这两个文件夹(此处采用if语句判断文件夹名称进行过滤,自我感觉不太好)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卑微小峰@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值