美文网首页java
java操作FTP服务文件

java操作FTP服务文件

作者: 星钻首席小管家 | 来源:发表于2021-03-10 11:10 被阅读0次

    1.添加依赖

    <!--ftp-->
            <dependency>
                <groupId>commons-net</groupId>
                <artifactId>commons-net</artifactId>
                <version>3.1</version>
            </dependency>
    

    2.FtpUtil

    @Data
    @Component
    public class FtpUtil {
    
        /** 本地字符编码 */
        private static String LOCAL_CHARSET = "GBK";
    
        // FTP协议里面,规定文件名编码为iso-8859-1
        private static String SERVER_CHARSET = "ISO-8859-1";
    
        /**
         * 日志对象
         **/
        private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);
    
        /**
         * 该目录不存在
         */
        public static final String DIR_NOT_EXIST = "该目录不存在";
    
        /**
         * "该目录下没有文件
         */
        public static final String DIR_CONTAINS_NO_FILE = "该目录下没有文件";
    
        /**
         * FTP地址
         **/
        @Value("${ftp.host}")
        private String ip;
        /**
         * FTP端口
         **/
        @Value("${ftp.port}")
        private int port;
        /**
         * FTP用户名
         **/
        @Value("${ftp.username}")
        private String userName;
        /**
         * FTP密码
         **/
        @Value("${ftp.password}")
        private String password;
    //    /**
    //     * FTP基础目录
    //     **/
    //    @Value("${ftp.basepath}")
    //    private String basePath;
    //
    //    /**
    //     * 本地字符编码
    //     **/
    //    private static String localCharset = "GBK";
    //
    //    /**
    //     * 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";
    //
    //    /**
    //     * 设置缓冲区大小4M
    //     **/
    //    private static final int BUFFER_SIZE = 1024 * 1024 * 4;
    
        /**
         * FTPClient对象
         **/
        private FTPClient ftpClient = null;
    
        private FTPSClient ftps = null ;
    
        /**
          * 本地存储基础目录
          **/
        @Value("${logging.file.path}")
        private String localPath;
    
        //构造方法初始化类
        public FtpUtil() {
        }
        //连接ftp
        public boolean connectServer() throws Exception{
            boolean flag = true;
            if (ftpClient == null || !ftpClient.isConnected()) {
                ftpClient = new FTPClient();
                ftpClient.connect(ip,port);
    
                log.info("Connected to " + ip);
                log.info(ftpClient.getReplyString());
    
                int reply = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    log.warn("FTP server refused connection.");
                    return false ;
                }
    
                boolean bok = ftpClient.login(userName, password);
                if (!bok)  {
                    try {
                        ftpClient.disconnect() ;
                        ftpClient = null ;
                    } catch (Exception e) { }
                    throw new Exception("can not login ftp server") ;
                }
    
                ftpClient.setBufferSize(1024);
                if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
                        "OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
                    LOCAL_CHARSET = "UTF-8";
                }
                ftpClient.setControlEncoding(LOCAL_CHARSET);
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                ftpClient.setDataTimeout(120000);
                ftpClient.enterLocalPassiveMode();
                ftpClient.setUseEPSVwithIPv4(false);
                ftpClient.setRemoteVerificationEnabled(false);
            }
            return flag;
        }
        //列出所有文件内容
        public List<String> listRemoteAllFiles(String path) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            FTPFile[] files = ftpClient.listFiles(path, new FTPFileFilter() {
                @Override
                public boolean accept(FTPFile file) {
                    if (file.isFile()){
                        String name = file.getName();
                        String suffix = name.substring(name.lastIndexOf(".") + 1);
                        if(!"zip".equalsIgnoreCase(suffix)){
                            return false;
                        }
                        return true ;
                    }
                    return false ;
                }}) ;
    
            List<String> list = new ArrayList() ;
            for (FTPFile file : files) {
                list.add(file.getName()) ;
            }
            this.disConnect();
            return list ;
        }
    
        public void disConnect() {
            try {
                if (ftpClient != null) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (Exception e) {
            }
    
        }
        //下载文件
        public boolean downloadFile(String remotePath, String fileName, String localPath) throws Exception {
    
            FileOutputStream fos = null ;
            try {
                File localFile = new File(localPath, fileName);
                fos = new FileOutputStream(localFile);
    
                ftpClient.enterLocalPassiveMode();
                ftpClient.changeWorkingDirectory(remotePath) ;
                boolean bok = ftpClient.retrieveFile(fileName, fos);
    
                fos.close() ;
                fos = null ;
    
                return bok ;
            } catch (Exception e) {
                throw e ;
            }
            finally {
                if (fos!=null) {
                    try {
                        fos.close() ;
                        fos = null ;
                    } catch (Exception e2) { }
                }
            }
    
        }
        //上传文件
        public boolean uploadFile(String remotePath, String filename, String localFilePath) throws Exception {
            FileInputStream fis = null ;
            try {
                fis = new FileInputStream(new File(localFilePath));
    
                ftpClient.enterLocalPassiveMode();
                ftpClient.changeWorkingDirectory(remotePath);
                boolean bok = ftpClient.storeFile(filename, fis);
    
                fis.close();
                fis = null ;
    
                return bok ;
            } catch (Exception e) {
                throw e ;
            }
            finally {
                if (fis!=null) {
                    try {
                        fis.close() ;
                        fis = null ;
                    } catch (Exception e2) { }
                }
            }
    
        }
        //删除文件
        public boolean deleteFile(String remotePath, String filename) throws Exception {
            ftpClient.changeWorkingDirectory(remotePath);
            boolean bok = ftpClient.deleteFile(filename) ;
            return bok ;
        }
    
        //列出指定日期戳之后的所有文件内容,只筛选zip类型文件,不包括文件夹,返回文件名列表
        public List<String> fileListAfterTime(String path, Date timestamp) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            FTPFile[] files = ftpClient.listFiles(path, new FTPFileFilter() {
                @Override
                public boolean accept(FTPFile file) {
                    if (file.isFile()){
                        Calendar timestampR = file.getTimestamp();
                        Date date = timestampR.getTime();
                        if(timestamp!=null && date.getTime()<timestamp.getTime()){
                            return false;
                        }
                        String name = file.getName();
                        String suffix = name.substring(name.lastIndexOf(".") + 1);
                        if(!"zip".equalsIgnoreCase(suffix)){
                            return false;
                        }
                        return true;
                    }
                    return false ;
                }}) ;
    
            List<String> list = new ArrayList() ;
            for (FTPFile file : files) {
                String name = file.getName();
                //String filePath = path + "/" +name;
                list.add(name) ;
            }
            this.disConnect();
            return list ;
        }
    
        //获取文件夹列表,业务需要文件夹name以“yyyy-MM-dd”命名,筛选掉name在指定日期之前的文件夹
        public List<String> folderListAfterTime(String path, Date timestamp) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            FTPFile[] files = ftpClient.listFiles(path, new FTPFileFilter() {
                @Override
                public boolean accept(FTPFile file) {
                    if (file.isDirectory()){
                        String name = file.getName();
                        try {
                            if(timestamp!=null){
                                Date date= new SimpleDateFormat("yyyy-MM-dd").parse(name);//字符串转成date对象类型
                                String format = new SimpleDateFormat("yyyy-MM-dd").format(timestamp);
                                Date startDate = getStartDate(format);
                                if(date.getTime()<startDate.getTime()){
                                    return false;
                                }
                            }
                        } catch (ParseException e) {
                            e.printStackTrace();
                            return false;
                        }
                        return true ;
                    }
                    return false ;
                }}) ;
    
            List<String> list = new ArrayList() ;
            for (FTPFile file : files) {
                String name = file.getName();
                //String filePath = path + "/" +name;
                list.add(name) ;
            }
            this.disConnect();
            return list ;
        }
    
        /**
         * 获取日期开始时间
         * @param date "2020-02-11"
         * @return eg:"2020-02-11 00:00:00"
         */
        public Date getStartDate(String date) {
            if(date == null) {
                return null;
            }
            try{
                Calendar c = Calendar.getInstance();
                c.setTime(DateUtils.parseDate(date, "yyyy-MM-dd"));
                c.set(Calendar.HOUR_OF_DAY, 0);
                c.set(Calendar.MINUTE, 0);
                c.set(Calendar.SECOND, 0);
                return c.getTime();
            }catch (ParseException e){
                return null;
            }
        }
    
        /** 判断Ftp目录是否存在 */
        public boolean isDirExist(String dir) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            boolean isExist;
            try {
                //判断目录是否存在
                isExist = ftpClient.changeWorkingDirectory(dir);
                System.out.println(isExist);
            } catch (IOException e) {
                e.printStackTrace();
                isExist = false;
            }
            this.disConnect();
            return isExist;
        }
    
        /**
         * @Description 批量下载指定目录下面指定文件名list的文件
         * @Param remotePath: 指定FTP上的目录
         * @Param nameList: 文件名list
         * @Param localPath: 本地目录
         * @return boolean
         */
        public List<String> downloadFile(String remotePath, List<String> nameList, String localPath) throws Exception {
            List<String> fileList = new ArrayList<>();
    
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            // 得到文件列表
            FTPFile[] files = ftpClient.listFiles(remotePath, new FTPFileFilter() {
                @Override
                public boolean accept(FTPFile file) {
                    if (file.isFile()){
                        System.out.println(file.getName());
                        if(!nameList.contains(file.getName())){
                            return false;
                        }
                        return true ;
                    }
                    return false ;
                }}) ;
    
    
    
            //遍历
            for (FTPFile file : files) {
                FileOutputStream fos = null ;
                try {
                    File localFile = new File(localPath+remotePath, file.getName());
    
                    // 判断目录是否存在
                    File dir = new File(localPath + remotePath);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
    
                    fos = new FileOutputStream(localFile);
    
                    ftpClient.enterLocalPassiveMode();
                    ftpClient.changeWorkingDirectory(remotePath) ;
                    boolean bok = ftpClient.retrieveFile(new String(file.getName().getBytes(LOCAL_CHARSET), "iso-8859-1"), fos);
    
                    fos.close() ;
                    fos = null ;
    
                    //this.disConnect();
                    fileList.add(localPath+remotePath + "/" + file.getName());
                } catch (Exception e) {
                    throw e ;
                }
                finally {
                    if (fos!=null) {
                        try {
                            fos.close() ;
                            fos = null ;
                        } catch (Exception e2) { }
                    }
                }
    
            }
            this.disConnect();
            return fileList;
        }
    
        //移动文件
        public boolean removeFile(String remotePath) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            // 解析路径
            String[] split = remotePath.split("/");
            String bak_ = "/" + remotePath.split("/")[1] + "_bak";
            String folder = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String bak_path = bak_ + "/" + folder;
    
            // 判断目录是否存在
            if (!this.CreateDirecroty(bak_path)) {
                this.disConnect();
                return false;
            }
    
            //开始移动
            this.disConnect();
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            String fileName = remotePath.substring(remotePath.lastIndexOf("/") + 1);
            fileName = new String(fileName.getBytes(LOCAL_CHARSET), "iso-8859-1");
            String filePath = bak_path + "/" + fileName;
            String lib = remotePath.substring(0,remotePath.lastIndexOf("/"));
            ftpClient.changeWorkingDirectory(lib);
            ftpClient.rename(fileName,filePath);
            //返回
            if (!this.isDirExist(filePath)) {
                this.disConnect();
                return false;
            }
            this.disConnect();
            return true;
        }
    
        //创建目录
        public boolean makeDirectory(String dir,String folder) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            boolean flag = true;
            try {
                if(ObjectUtils.isNotEmpty(folder)){
                    ftpClient.changeWorkingDirectory(new String(folder));
                }
                flag = ftpClient.makeDirectory(dir);
                if (flag) {
                    logger.debug("创建文件夹" + dir + " 成功!");
    
                } else {
                    logger.debug("创建文件夹" + dir + " 失败!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            this.disConnect();
            return flag;
        }
    
    
        //创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
        public boolean CreateDirecroty(String remote) throws Exception {
            this.connectServer();
            ftpClient.enterLocalPassiveMode();
            boolean success = true;
            String directory = remote + "/";
            //        String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
            // 如果远程目录不存在,则递归创建远程服务器目录
            if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(new String(directory))) {
                int start = 0;
                int end = 0;
                if (directory.startsWith("/")) {
                    start = 1;
                } else {
                    start = 0;
                }
                end = directory.indexOf("/", start);
                String path = "";
                String paths = "";
                while (true) {
    
                    String subDirectory = new String(remote.substring(start, end).getBytes(LOCAL_CHARSET), "iso-8859-1");
                    String lib = path;
                    path = path + "/" + subDirectory;
                    if (!this.isDirExist(path)) {
                        if (!makeDirectory(subDirectory,lib)) {
                            logger.debug("创建目录[" + subDirectory + "]失败");
                            this.disConnect();
                            success =  false;
                        }
                    }
                    this.disConnect();
                    this.connectServer();
                    ftpClient.enterLocalPassiveMode();
                    ftpClient.changeWorkingDirectory(path);
    
                    paths = paths + "/" + subDirectory;
                    start = end + 1;
                    end = directory.indexOf("/", start);
                    // 检查所有目录是否创建完毕
                    if (end <= start) {
                        break;
                    }
                }
            }
            this.disConnect();
            return success;
        }
    
    }
    

    3.注意事项:调试的时候发现调用disConnect后severlet置空了,但ftpclient并不为null,暂时没找到原因

    相关文章

      网友评论

        本文标题:java操作FTP服务文件

        本文链接:https://www.haomeiwen.com/subject/jkcwqltx.html