JAVA实现文件上传和下载——FTP篇(续)

简介:

续!!!
前一篇介绍将文件上传到ftp服务器和下载以及直接用ftp路径下载的功能。
此篇主要介绍ftp上传下载的另一个工具类,实现步骤一样,未使用ftp连接池,随用随关。
本次实例,内网连接,主动模式!

FTP文件上传和下载:

1.加入依赖,导包(同上篇)
2.在yml配置文件中配置相关信息(同上篇)
3.在config包新建FtpProperties类获取yml配置(同上篇)
4.controller层(同上篇)
5.service层

@Autowired
private FtpProperties ftpProperties;

private FtpUtils client;
    
//ftp文件上传
public String upload(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return null;
        }
        //获取文件名
        String fileName = file.getOriginalFilename();
        Objects.requireNonNull(fileName, "the file uploaded is null");
        //获取文件后缀
        String fileType = getFileType(fileName);
        try (FtpUtil client = FtpUtil.getInstance(ftpProperties.getInnerIp(), Integer.parseInt(ftpProperties.getInnerPort()),
                ftpProperties.getUserName(), ftpProperties.getPassword())) {
            //开启ftp连接
            boolean isOpen = client.open();
            if (isOpen) {
                String date = formatDate("yyyy/MM/", System.currentTimeMillis());
                String name = UUID.randomUUID().toString() + fileType;
                String filePath = ftpProperties.getFilePath() + date;
                //ftp创建目录路径
                boolean success = client.mkdirs(filePath);
                if (success) {
                    client.upload(name, filePath, file.getBytes(), true);
                } else {
                    log.error("mkdir is error: {}", "创建路径失败!");
                    return null;
                }
                return date + name;
            }
        } catch (Exception e) {
            log.error("upload error" + e.getMessage());
            throw new BadRequestException(e.getMessage());
        }
        //记得关闭连接
        if (Objects.nonNull(this.client)) {
            this.client.close();
        }
        return null;
    }

public void download(Long id, HttpServletRequest req, HttpServletResponse res){
    if (id != null) {
        File entity = fileRepository.findById(id).get();
        String path = ftpProperties.getFilePath() + entity.getFilePath();
        String fileName = entity.getName();
        // 重要,需要设置此值,否则下载后打开excel会提示文件需要修复
        res.setContentLength(entity.getFileSize());

        FtpUtil client = FtpUtil.getInstance(ftpProperties.getInnerIp(), Integer.parseInt(ftpProperties.getInnerPort()),
                ftpProperties.getUserName(), ftpProperties.getPassword());
        boolean isOpen = client.open();
        //判断ftp服务器文件是否存在
        boolean containsFile = client.containsFile(ftpPath);
	    if(!containsFile){
	        LOG.error("The file {} in ftp is not existed!", ftpPath);
	        return;
	    }
        if (isOpen) {
            try{
                String filePath = path.substring(0, path.lastIndexOf("/"));
                //根据ftp存储路径自行填写filePath
                client.download(filePath, fileName, res.getOutputStream());
            } catch (Exception e) {
                log.error("download error" + e.getMessage());
                throw new BadRequestException(e.getMessage());
            }
        }
        //记得关闭连接
	    if (Objects.nonNull(this.client)) {
	         this.client.close();
	    }
    }
}

6.FtpUtil工具类

package cn.com.sealevel.upgrader.common;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.net.SocketException;

/**
 * FTP工具类
 */
@Slf4j
public class FtpUtils {

    private static FtpUtils instance = null;
    private static FTPClient ftpClient = null;
    private String server;
    private int port;
    private String username;
    private String password;

    public FtpUtils(String server, int port, String username, String password) {
        super();
        this.server = server;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    public static FtpUtils getInstance(String server, int port, String username, String password) {
        if (instance == null) {
            instance = new FtpUtils(server, port, username, password);
        }
        ftpClient = new FTPClient();
        return instance;
    }

    /**
     * 连接FTP服务器
     *
     * @return
     */
    private boolean connect() {
        boolean stat = false;
        try {
            if (ftpClient.isConnected()) {
                return true;
            }
            ftpClient.connect(server, port);
            stat = true;
        } catch (SocketException e) {
            stat = false;
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            stat = false;
            log.error(e.getMessage(), e);
        }
        return stat;
    }

    /**
     * 打开FTP服务器
     *
     * @return
     */
    public boolean open() {
        if (!connect()) {
            return false;
        }

        try {
            // 设置用户名和密码
            ftpClient.login(username, password);
            // 设置连接超时时间,5000毫秒
            ftpClient.setConnectTimeout(500000);
            // 设置中文编码集,防止中文乱码
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 检测连接是否成功
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                log.error("The password or username is invalid!");
                close();
                return false;
            }
            return true;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 关闭FTP服务器
     */
    public void close() {
        try {
            if (ftpClient != null && ftpClient.isConnected()) {
                ftpClient.logout();
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            if (ftpClient != null) {
                try {
                    ftpClient.disconnect();
                    ftpClient = null;
                } catch (IOException ioe) {
                    log.error(ioe.getMessage(), ioe);
                }
            }
        }
    }

   /**
     * 上传文件到FTP服务器
     *
     * @param filename 文件名
     * @param path     ftp上文件存储路径
     * @param data     文件内容
     * @param isActive     主动模式/被动模式
     * @return 上传是否成功
     */
    public boolean upload(String filename, String path, byte[] data, boolean isActive) {
        boolean stat = false;
        try (ByteArrayInputStream input = new ByteArrayInputStream(data)) {
            ftpClient.changeWorkingDirectory(path);
            ftpClient.setBufferSize(1024);
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.setRemoteVerificationEnabled(false);
            if (isActive) {
                ftpClient.enterLocalActiveMode();
            } else {
                ftpClient.enterLocalPassiveMode();
            }
            stat = ftpClient.storeFile(new String(filename.getBytes("utf-8"), "iso-8859-1"), input);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return stat;
    }

    /**
     * 从本地磁盘上传文件到FTP服务器
     *
     * @param localFile 本地路径
     * @param filename  文件名
     * @param path      ftp上文件存储路径
     * @param isActive  主动模式/被动模式
     * @return 上传是否成功
     */
    public boolean upload(String localFile, String filename, String path, boolean isActive) {
        boolean stat = false;
        File file = new File(localFile);
        try (InputStream in = new FileInputStream(file)) {
            ftpClient.changeWorkingDirectory(path);
            ftpClient.setBufferSize(1024);
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.setRemoteVerificationEnabled(false);
            if (isActive) {
                ftpClient.enterLocalActiveMode();
            } else {
                ftpClient.enterLocalPassiveMode();
            }
            stat = ftpClient.storeFile(new String(filename.getBytes("utf-8"), "iso-8859-1"), in);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return stat;
    }

    /***
     * 创建多个层级目录
     *
     * @param dir
     *            dong/zzz/ddd/ewv
     * @return
     */
    public boolean mkdirs(String dir) {
        String[] dirs = dir.split("/");
        if (dirs.length == 0) {
            return false;
        }
        boolean stat = false;
        try {
            ftpClient.changeToParentDirectory();
            for (String dirss : dirs) {
                ftpClient.makeDirectory(dirss);
                ftpClient.changeWorkingDirectory(dirss);
            }

            ftpClient.changeToParentDirectory();
            stat = true;
        } catch (IOException e) {
            stat = false;
            log.error(e.getMessage(), e);
        }
        return stat;
    }

    /**
     * 从FTP服务器下载文件到指定路径localPath 
     *
     * @param ftpPath   FTP服务器中文件所在路径 格式: ftptest/aa
     * @param localPath 下载到本地的位置 格式:H:/download
     * @param fileName  文件名称
     */
    public void download(String ftpPath, String localPath, String fileName) {
        File localFile = new File(localPath + File.separatorChar + fileName);
        try (OutputStream os = new FileOutputStream(localFile)) {
            //支持中文
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalActiveMode();
            //ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);
            ftpClient.retrieveFile(new String(fileName.getBytes("utf-8"), "iso-8859-1"), os);
        } catch (FileNotFoundException e) {
            log.error("没有找到" + ftpPath + "文件");
            log.error(e.getMessage(), e);
        } catch (SocketException e) {
            log.error("连接FTP失败.");
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error("文件读取错误。");
            log.error(e.getMessage(), e);
        }
    }
    
   /**
     * 从FTP服务器下载文件到输出流
     *
     * @param ftpPath      FTP服务器中文件所在路径 格式: ftptest/aa
     * @param fileName     文件名称
     * @param outputStream 输出流
     */
    public void download(String ftpPath, String fileName, OutputStream outputStream) {
        try {
            //支持中文
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalActiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);
            ftpClient.retrieveFile(new String(fileName.getBytes("utf-8"), "iso-8859-1"), outputStream);
        } catch (FileNotFoundException e) {
            log.error("没有找到" + ftpPath + "文件");
            log.error(e.getMessage(), e);
        } catch (SocketException e) {
            log.error("连接FTP失败.");
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error("文件读取错误。");
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 判断ftp服务器文件是否存在
     *
     * @param folderPath 需要解析的的文件夹
     * @return
     */
    public boolean containsFile(String folderPath) {
        boolean flag = false;
        try {
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.setRemoteVerificationEnabled(false);
            ftpClient.enterLocalActiveMode();
            //ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFileArr = ftpClient.listFiles(folderPath);
            if (ftpFileArr.length > 0) {
                flag = true;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return flag;
    }

    public FTPFile[] listFiles(String directory) {
        try {
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalActiveMode();
            ftpClient.changeWorkingDirectory(directory);
            return ftpClient.listDirectories();
        } catch (IOException e) {
            log.error("listFiles 文件读取错误。");
        }
        return new FTPFile[0];
    }
}

当FTP上传文件出现这个报错信息:Host attempting data connection 192.168.2.113 is not same as server 10.20.61.140
加上这句代码可以解决:ftpClient.setRemoteVerificationEnabled(false); 这句代码的意思是:取消服务器获取自身Ip地址和提交的host进行匹配,否则当不一致时报出以上异常。
complete!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值