美文网首页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服务文件

    1.添加依赖 2.FtpUtil 3.注意事项:调试的时候发现调用disConnect后severlet置空了,但...

  • 【java】Ftp文件操作

    1 jar包下载与导入 使用java对ftp进行操作需要使用commons-net-3.5.jar包,下载地址为h...

  • java中如何检验ftp服务器中指定文件是否存在

    java中如何检验ftp服务器中指定文件是否存在 检验思路: 首先需要连接“ftp”服务器,然后设置文件类型为二进...

  • Java 实现ftp文件上传

    在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件、下载文件,本文详细介绍如何利用FTPClie...

  • JAVA中使用FTPClient实现文件上传下载

    在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件、下载文件,本文简单介绍如何利用jakarta...

  • FTP

    Menu 1.创建FTP服务器2.递归删除FTP服务器文件3.递归下载FTP服务器文件4.递归上传FTP服务器文件...

  • 4.ftp文件服务&ssh服务搭建

    ftp文件服务搭建 1. 搭建ftp服务 FTP:文件传输协议,用于文件在本地和服务器上的双向传输,"下载"(Do...

  • JAVA FTPClient FTP简单操作

    在项目中,经常会用到FTP服务器,这里做了一个简单的联系,基于FTPClient 对FTP文件进行操作

  • java对象池apache common-pool2应用示例-F

    背景 之前写过java调用ftpClient实现大文件传输的文章:ubuntu20-04配置ftp服务器-java...

  • linux搭建ftp

    Centos7 命令使用总结 java完成ftp传输(将文件上传至静态资源服务器) ftp一些概念了解 Linux...

网友评论

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

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