springboot项目 从FTP服务器下载文件到本地,并读取文件中的内容代码示例(亲测可用)

Posted 小志的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot项目 从FTP服务器下载文件到本地,并读取文件中的内容代码示例(亲测可用)相关的知识,希望对你有一定的参考价值。

目录

一、引入依赖包

  • pom文件引入依赖包

    <dependency>
     	  <groupId>commons-net</groupId>
        <artifactId>commons-net</artifactId>
        <version>3.6</version>
    </dependency>
    

二、FTP工具类 代码示例

  • FTP工具类

    package com.xz.jdk11.ftp;
    
    import cn.hutool.core.util.StrUtil;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import lombok.extern.slf4j.Slf4j;
    
    @Slf4j
    public class FtpUtil 
        /** FTP地址 **/
        private String ftpAddress;
    
        /** FTP端口 **/
        private int ftpPort;
    
        /** FTP用户名 **/
        private String ftpUsername;
    
        /** FTP密码 **/
        private String ftpPassword;
    
        /** FTP基础目录 **/
        private String basePath = "/";
    
        /** 初始化登录ftp 默认false 登录成功返回true **/
        private Boolean b = false;
    
        public Boolean getB() 
            return b;
        
    
        /**
         *   新添,初始化登录ftp,连接失败 返回b 为:false ,成功 为 :true
         * @param ftpUsername 账号
         * @param ftpPassword 密码
         * @param basePath  FTP根目录
         */
        public FtpUtil(String ftpAddress, int ftpPort, String ftpUsername, String ftpPassword, String basePath) 
            this.ftpAddress = ftpAddress;
            this.ftpPort = ftpPort;
            this.ftpUsername = ftpUsername;
            this.ftpPassword = ftpPassword;
            this.basePath = basePath;
            b = login(ftpAddress, ftpPort, this.ftpUsername, this.ftpPassword);
        
    
        /** 本地字符编码  **/
        private static String localCharset = "UTF-8";
    
        /** FTP协议里面,规定文件名编码为iso-8859-1 **/
        private static String serverCharset = "ISO-8859-1";
    
        /** UTF-8字符编码 **/
        private static final String CHARSET_UTF8 = "UTF-8";
    
        /** OPTS UTF8字符串常量 **/
        private static final String OPTS_UTF8 = "OPTS UTF8";
    
        /** 设置缓冲区大小 **/
        private static final int BUFFER_SIZE = 1024 * 1024 * 10;
    
        /** FTPClient对象 **/
        private static FTPClient ftpClient = null;
    
        /**
         * 下载指定文件到本地
         *
         * @param ftpPath FTP服务器文件相对路径,例如:test/123
         * @param fileName 要下载的文件名,例如:test.txt
         * @param savePath 保存文件到本地的路径,例如:D:/test
         * @return 成功返回true,否则返回false
         */
        public boolean downloadFile(String ftpPath, String fileName, String savePath) 
            // 登录
            boolean flag = false;
            if (ftpClient != null) 
                try 
                    log.info( "[下载]FTP服务器全路径===",basePath + ftpPath);
                    String path = changeEncoding(basePath + ftpPath);
                    // 判断是否存在该目录
                    if (!ftpClient.changeWorkingDirectory(path)) 
                        log.error(basePath + ftpPath + "该目录不存在");
                        return flag;
                    
                    ftpClient.enterLocalPassiveMode();  // 设置被动模式,开通一个端口来传输数据
                    String[] fs = ftpClient.listNames();
                    // 判断该目录下是否有文件
                    if (fs == null || fs.length == 0) 
                        log.error(basePath + ftpPath + "该目录下没有文件");
                        return flag;
                    
                    for (String ff : fs) 
                        String ftpName = new String(ff.getBytes(CHARSET_UTF8), CHARSET_UTF8);
                        if (ftpName.equals(fileName)) 
                            log.info("ftp服务器中文件名称=====",ftpName);
                            log.info("本地保存路径savePath=====",savePath);
                            File file = new File(savePath + '/' + ftpName);
                            try 
                                OutputStream os = new FileOutputStream(file);
                                flag = ftpClient.retrieveFile(ff, os);
                                log.info("下载文件成功,文件名称:",fileName);
                             catch (Exception e) 
                                log.error(e.getMessage(), e);
                            
                            break;
                        
                    
                 catch (IOException e) 
                    log.error("下载文件失败", e);
                
            
            return flag;
        
    
        /**
         * 根据名称获取文件,以字节数组返回
         *
         * @param ftpPath FTP服务器文件相对路径,例如:test/123
         * @param fileName 文件名,例如:test.xls
         * @return byte[] 字节数组对象
         */
        public byte[] getFileBytesByName(String ftpPath, String fileName) 
            // 登录
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            if (ftpClient != null) 
                try 
                    log.info( "[解析]FTP服务器全路径===",basePath + ftpPath);
                    String path = changeEncoding(basePath + ftpPath);
                    // 判断是否存在该目录
                    if (!ftpClient.changeWorkingDirectory(path)) 
                        log.error(basePath + ftpPath + "该目录不存在");
                        return byteStream.toByteArray();
                    
                    ftpClient.enterLocalPassiveMode();  // 设置被动模式,开通一个端口来传输数据
                    String[] fs = ftpClient.listNames();
                    // 判断该目录下是否有文件
                    if (fs == null || fs.length == 0) 
                        log.error(basePath + ftpPath + "该目录下没有文件");
                        return byteStream.toByteArray();
                    
                    for (String ff : fs) 
                        String ftpName = new String(ff.getBytes(CHARSET_UTF8), CHARSET_UTF8);
                        if (ftpName.equals(fileName)) 
                            log.info("获取文件内容操作,ftp服务器中文件名称=====",ftpName);
                            try 
                                InputStream is = ftpClient.retrieveFileStream(ff);
                                byte[] buffer = new byte[BUFFER_SIZE];
                                int len;
                                while ((len = is.read(buffer, 0, BUFFER_SIZE)) != -1) 
                                    byteStream.write(buffer, 0, len);
                                
                             catch (Exception e) 
                                log.error(e.getMessage(), e);
                            
                            break;
                        
                    
                 catch (IOException e) 
                    log.error("获取文件失败", e);
                 finally 
                    Boolean close = closeConnect();
                    log.info("连接是否关闭:" + close);
                
            
            return byteStream.toByteArray();
        
    
        /**
         * 连接FTP服务器
         *
         * @param address  地址,如:127.0.0.1
         * @param port     端口,如:21
         * @param username 用户名,如:root
         * @param password 密码,如:root
         */
        private Boolean login(String address, int port, String username, String password) 
            ftpClient = new FTPClient();
            try 
                ftpClient.connect(address, port);
                ftpClient.login(username, password);
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                int reply = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) 
                    closeConnect();
                    log.error("FTP服务器连接失败:" + "地址:" + address + "  端口:" + port + "  用户名:" + username + "  密码:" + password);
                 else 
                    b = true;
                
             catch (Exception e) 
                log.error("FTP登录失败", e);
            
            return b;
        
    
        /**
         * 关闭FTP连接
         *
         */
        public Boolean closeConnect() 
            Boolean b = false;
            if (ftpClient != null && ftpClient.isConnected()) 
                try 
                    ftpClient.logout();
                    b = true;
                 catch (IOException e) 
                    log.error("关闭FTP连接失败", e);
                
            
            return b;
        
    
        /**
         * FTP服务器路径编码转换
         *
         * @param ftpPath FTP服务器路径
         * @return String
         */
        private static String changeEncoding(String ftpPath) 
            String directory = null;
            try 
                if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(OPTS_UTF8, "ON"))) 
                    localCharset = CHARSET_UTF8;
                
                directory = new String(ftpPath.getBytes(CHARSET_UTF8), CHARSET_UTF8);
             catch (Exception e) 
                log.error("路径编码转换失败", e);
            
            return directory;
        
    
        private boolean isDatFile(String fileName) 
            if (StrUtil.isNotBlank(fileName)) 
                int length = fileName.length();
                int index = fileName.indexOf(".");
                if (index == -1) 
                    return false;
                
                if (StrUtil.equals(fileName.substring(index + 1, length), "dat")) 
                    return true;
                
            
            return false;
        
    
    
    

三、模拟实体类(业务逻辑处理用)代码示例

  • 实体类

    package com.xz.jdk11.ftp;
    
    import lombok.Data;
    import lombok.ToString;
    
    /**
     * @description:
     * @author: xz
     */
    @Data
    @ToString
    public class UserBean 
        private String id;
        private String name;
    
    

四、测试类 代码示例

  • 测试类

    package com.xz.jdk11.ftp;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.transaction.annotation.Transactional;
    import java.io.File;
    import java.io.UnsupportedEncodingException;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @description:
     * @author: xz
     */
    @Slf4j
    public class FtpUtilTest 
        public static void main(String[] args) 
            FtpUtilTest ftpUtilTest = new FtpUtilTest();
            ftpUtilTest.longinFtp("filename");
        
        /**
         * 登录ftp,下载文件
         * @param XMLFileName 需要下载的文件名称
         *
         * */
        public List<UserBean> longinFtp(String XMLFileName) 
            List<UserBean> userBeanList = null;
            /**
             * 1、登录ftp
             * */
            FtpUtil ftpUtil = new FtpUtil("localhost", 21, "username", "password", "/");
            Boolean b = ftpUtil.getB();
            if (b) 
                log.info("连接Ftp成功==========");
            
            //localFilePath 保存文件到本地服务器的路径
            String filepath="/home/file";
            String contextPath="/springboot";
            String localFilePath=filepath+contextPath+ File.separatorChar +"ftp";
            //ftpPath FTP服务器文件相对路径,例如:test/123
            String ftpPath="";
            /**
             * 2、下载文件
             * */
            boolean b1 = ftpUtil.downloadFile(ftpPath, XMLFileName, localFilePath);
            if(b1)
                /**
                 * 3、读取文件内容
                 * */
                byte[] bytes = ftpUtil.getFileBytesByName(ftpPath, XMLFileName);
                if (bytes.length == 0) 
                    log.info("获取到的文件数据为空");
                    return userBeanList;
                
                /**
                 * 3、文件内容物业逻辑处理
                 * */
                userBeanList = handleBytes(bytes);
            
            if (ftpUtil.closeConnect()) 
                log.info("Ftp连接关闭");
            
            return userBeanList;
        
    
        /**
         *
         * */
        @Transactional(rollbackFor = Exception.class)
        public List<UserBean> handleBytes(byte[] bytes) 
            String res = null;
            try 
                //此处根据你在ftp上文件的编码自主选择
                res = new String(bytes, "GBK");
                log.info("获取到的文件数据:",res);
             catch (UnsupportedEncodingException e) 
                e.printStackTrace();
            
            List<UserBean> list=new ArrayList<>();
            if (res != null) 
                log.info("读取到的文件内容物业逻辑处理==========> start");
             else 
                log

    以上是关于springboot项目 从FTP服务器下载文件到本地,并读取文件中的内容代码示例(亲测可用)的主要内容,如果未能解决你的问题,请参考以下文章

    Apache Camel 与 Spring Boot 集成,通过FTP定时采集处理文件

    Springboot使用ftp进行文件上传下载

    写个小程序从FTP上下载文件

    从 FTP 服务器下载所有文件 [关闭]

    如何从 FTP 下载文件并使用 PHP 将其流式传输到客户端

    远程FTP下载文件