Java使用FTP实现文件上传、下载、删除

Linux上搭建一个FTP文件服务器,很简单,网上一搜就有教程,下面是使用FTPClient实现的工具类:

package cn.rivamed.irsmartor.common;

import cn.rivamed.config.FtpProperties;
import cn.rivamed.irsmartor.enums.GlobleEnum;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DateFormat;
import java.util.Date;
import java.util.UUID;

/**
 *
 *
 *
 * @ClassName: FTPUtils
 * @Description
 * @Author wuyong
 * @Date 2019/8/15 16:38 
 * @version V1.0
 */
@SuppressWarnings("all")
@Slf4j
public class FtpUtil {

    /**
     * @Description 上传文件
     * @param ftpProperties
     * @param inputStream
     * @param fileName
     * @Date 2019/8/16 13:57
     * @Author wuyong
     * @return java.lang.String
     **/
    public static String upload(FtpProperties ftpProperties, FileInputStream inputStream, String originFileName) throws IOException {
        FTPClient ftp = null;
        String path;
        String fileName;
        try {
            // 建立连接
            ftp = connect(ftpProperties);

            // 创建目录
            path = mkDir(ftpProperties, ftp);

            // 切换到上传目录
            changeToUploadDirectory(ftp, path);

            // 设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);

            // 上传文件
            fileName = upload(ftp, inputStream, originFileName);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (ftp != null) {
                ftp.logout();
                if (ftp.isConnected()) {
                    ftp.disconnect();
                }
            }
        }
        return path + fileName;
    }

    /**
     * @Description 下载
     * @param ftpProperties
     * @param serverUrl
     * @param fileName
     * @param response
     * @Date 2019/8/16 15:15
     * @Author wuyong
     * @return void
     **/
    public static void download(FtpProperties ftpProperties, String serverUrl, String originFileName, HttpServletResponse response) throws IOException {
        FTPClient ftpClient = null;
        OutputStream outputStream = null;
        try {
            // 建立连接
            ftpClient = connect(ftpProperties);

            // 切换FTP目录
            String path = serverUrl.substring(0, serverUrl.lastIndexOf("/"));
            String fileName = serverUrl.substring(serverUrl.lastIndexOf("/") + 1);
            boolean b = ftpClient.changeWorkingDirectory(path);
            if (!b) {
                return;
            }
            log.info("切换到下载目录成功:{}", path);

            // 下载
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                // 如果支持中文,只需reEncode(fileName)
                if (file.isFile() && file.getName().equals(fileName)) {
                    outputStream = response.getOutputStream();
                    response.setCharacterEncoding("utf-8");
                    response.setContentType("multipart/form-data");
                    response.setHeader("Content-Disposition", "attachment;fileName=" + new String(originFileName.getBytes("UTF-8"), "ISO-8859-1"));
                    ftpClient.retrieveFile(file.getName(), outputStream);
                    outputStream.close();
                    log.info("下载成功");
                }
            }
        } finally {
            if (ftpClient != null) {
                // 释放资源
                ftpClient.logout();
                if (ftpClient.isConnected()) {
                    try {
                        ftpClient.disconnect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * @Description 删除
     * @param pathname
     * @param filename
     * @Date 2019/8/16 15:31
     * @Author wuyong
     * @return boolean
     **/
    public static boolean delete(FtpProperties ftpProperties, String serverUrl) throws Exception {
        FTPClient ftpClient = null;
        try {
            // 连接
            ftpClient = connect(ftpProperties);

            // 切换FTP目录
            String path = serverUrl.substring(0, serverUrl.lastIndexOf("/"));
            String fileName = serverUrl.substring(serverUrl.lastIndexOf("/") + 1);
            boolean b = ftpClient.changeWorkingDirectory(path);
            if (!b) {
                return false;
            }

            // 删除
            return ftpClient.dele(reEncode(fileName)) > 0;
        } finally {
            if (ftpClient != null) {
                ftpClient.logout();
                if (ftpClient.isConnected()) {
                    try {
                        ftpClient.disconnect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    private static String upload(FTPClient ftp, InputStream inputStream, String originFileName) throws IOException {
        // 防止文件名重复造成文件被覆盖,重新生成一个文件名保存
        String fileName = UUID.randomUUID().toString().replace("-", "") + originFileName.substring(originFileName.lastIndexOf("."));
        boolean b = ftp.storeFile(reEncode(fileName), inputStream);
        if (!b) {
            throw new BusinessException(GlobleEnum.UPLOAD_FAIL.getCode(), GlobleEnum.UPLOAD_FAIL.getMessage());
        }
        log.info("上传成功");
        return fileName;
    }

    private static void changeToUploadDirectory(FTPClient ftp, String path) throws IOException {
        boolean b = ftp.changeWorkingDirectory(path);
        if (!b) {
            throw new BusinessException(GlobleEnum.CHANGE_DIR_FAIL.getCode(), GlobleEnum.CHANGE_DIR_FAIL.getMessage() + ": " + path);
        }
        log.info("切换到上传目录成功");
    }

    private static String mkDir(FtpProperties ftpProperties, FTPClient ftp) throws IOException {
        // 服务器保存根路径,如果配置的基础路径不是以/结尾,则加一个/
        String path = ftpProperties.getPath();
        path = StringUtils.isBlank(path) ? "/data/" : path;
        path = path.startsWith("/") ? path : "/" + path;
        path = path.endsWith("/") ? path : path + "/";
        DateFormat dateFormat = DateFormatUtil.applyPattern("yyyy/MM/dd").get();
        // 以日期作为子目录
        String childPath = dateFormat.format(new Date());
        for (String p : childPath.split("/")) {
            path = path + p + "/";
            path = reEncode(path);
            // 防止中文乱码
            ftp.makeDirectory(path);
            if (!ftp.changeWorkingDirectory(path)) {
                throw new BusinessException(GlobleEnum.MK_DIR_FAIL.getCode(), GlobleEnum.MK_DIR_FAIL.getMessage() + ": " + path);
            }
            log.info("创建目录: {} 成功:", path);
        }
        return path;
    }

    private static FTPClient connect(FtpProperties ftpProperties) throws IOException {
        String host = ftpProperties.getHost();
        int port = ftpProperties.getPort();
        String username = ftpProperties.getUsername();
        String password = ftpProperties.getPassword();
        Assert.notEmpty(username, "ftp username is required");
        Assert.notEmpty(password, "ftp password is required");

        FTPClient ftp = new FTPClient();
        ftp.connect(host, port);
        ftp.login(username, password);
        int replyCode = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            throw new BusinessException(GlobleEnum.CONNECT_FTP_FAIL.getCode(), GlobleEnum.CONNECT_FTP_FAIL.getMessage());
        }
        log.info("连接ftp服务器成功!");
        return ftp;
    }

    private static String reEncode(String str) throws UnsupportedEncodingException {
        return new String(str.getBytes("GBK"), "iso-8859-1");
    }

}
发布了114 篇原创文章 · 获赞 91 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qmqm011/article/details/99714881
今日推荐