FTP常用操作 做个记录


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/***
 * @Description 描述
 * @classname FtpUtil
 * @Date 2021/5/28 10:04
 */
@Slf4j
@Component
public class FtpUtil {

    private static Long userSizes = 0L;

    private final static String DEFAULT_ENCODING = "ISO-8859-1";

   

    @Autowired
    private FtpClientFactory ftpClientFactoryPools;

    private static FtpClientFactory ftpClientFactory;

    @PostConstruct
    public void init() {
        ftpClientFactory = ftpClientFactoryPools;
    }

    /**
     * 删除文件
     *
     * @param fileName
     * @return
     * @throws IOException
     */
    public static boolean deleteFile(String fileName) throws IOException {
        FTPClient ftpClient = null;
        boolean result = false;
        try {
            ftpClient = ftpClientFactory.makeFtpClient();
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClientFactory.destroyClient(ftpClient);
                return result;
            }
            result = ftpClient.deleteFile(new String(fileName.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING));
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            ftpClientFactory.destroyClient(ftpClient);
        }
        return result;
    }

    /**
     * 创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
     *
     * @param remote
     * @return
     * @throws IOException
     * @date 创建时间:2017年6月22日 上午11:51:33
     */
    public static BaseResp CreateDirecroty(String remote, String workPath)
            throws IOException {
        BaseResp baseResp = null;
        FTPClient ftp = null;
        try {
            ftp = ftpClientFactory.makeFtpClient();
            int reply;
            // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClientFactory.destroyClient(ftp);
            }
            if (!ftp.changeWorkingDirectory(new String(workPath.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
                return baseResp = new BaseResp(CommonEnum.DIR_IS_NOT_EXITIS);
            }
            String[] dir = remote.split("/");
            List<String> list = new ArrayList<>();
            for (int i = 0; i < dir.length; i++) {
                if (StringUtils.isNotEmpty(dir[i])) {
                    list.add(dir[i]);
                }
            }
            for (String li : list) {
                String subDirectory = new String(li.getBytes("UTF-8"), DEFAULT_ENCODING);
                if (!ftp.changeWorkingDirectory(subDirectory)) {
                    log.info("目录不存在,创建目录");
                    ftp.makeDirectory(subDirectory);
                    ftp.changeWorkingDirectory(subDirectory);
                } else {
                    ftp.changeWorkingDirectory(subDirectory);
                    baseResp = new BaseResp(CommonEnum.FILE_EXITIS);
                    log.info("目录已存在", subDirectory);
                    continue;
                }
            }
        } catch (Exception e) {
            ftpClientFactory.destroyClient(ftp);
            log.error(e.toString());
            return baseResp = new BaseResp(CommonEnum.FAIL);
        }
        return baseResp = new BaseResp(CommonEnum.SUCCESS);
    }

    /***
     * 删除FTP目录
     * 目录路径只能从最后一个往前面删 比如:/tools/test/test 删除的话是先最后一个,如果要删除全部纪要循环
     */
    public static boolean deleteDir(String path) {
        boolean flag = false;
        FTPClient ftp = null;
        try {
            ftp = ftpClientFactory.makeFtpClient();
            //先判断要删除的文件存不存在
            if (!ftp.changeWorkingDirectory(path)) {
                return flag;
            }
            log.info("当前工作目录" + ftp.printWorkingDirectory());
            FTPFile[] file = ftp.listFiles(path);
            if (file != null) {
                log.info("该文件夹下存在文件");
                return false;
            }
            while (true) {
                //删除当前文件夹 path="/tools/test/test1
                if (ftp.removeDirectory(path)) {
                    //回到父级文件 /tools/test
                    ftp.changeToParentDirectory();
                    //得到当前文件夹路径 /tools/test
                    path = ftp.printWorkingDirectory();
                    log.info("上级文件夹路径:" + ftp.changeToParentDirectory());
                    log.info("当前工作目录" + ftp.printWorkingDirectory());
                    if (path.equals("/tools")) {
                        flag = true;
                        break;
                    }
                }
            }
        } catch (Exception e) {
            log.error("FTP操作出错,请联系管理员", e.toString());
        } finally {
            ftpClientFactory.destroyClient(ftp);
        }
        return flag;
    }

    /**
     * 获取用户FPT目录的文件列表信息
     *
     * @param path
     * @return
     */
    public static BaseResp getFtpFileList(String path, String workPath) {
        BaseResp resp = null;
        String userPath = path;
        List<FileEntityDto> list = new ArrayList<>();
        FTPClient ftp = null;
        try {
            ftp = ftpClientFactory.makeFtpClient();
            ftp.setControlEncoding("UTF-8");
            path = workPath + path;
            path = new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
            if (!ftp.changeWorkingDirectory(path)) {
                resp = new BaseResp(CommonEnum.FILE_NO_EXITIS);
                resp.setMessage("该文件夹不存在,请检查!");
                return resp;
            }
            Long sumSzie = 0L;
            FTPFile[] ftpFile = ftp.listFiles(path);
            for (FTPFile file : ftpFile) {
                FileEntityDto fileEntityDto = new FileEntityDto();
                //如果是文件夹 获取其里全部文件 得到文件大小 统计文件夹占用空间大小
                if (file.getType() == 1) {
                    FTPFile[] files = ftp.listFiles(path + "/" + file.getName());
                    if (ObjectUtils.isNotEmpty(files)) {
                        for (FTPFile fi : files) {
                            sumSzie += fi.getSize();
                        }
                    }
                }
                fileEntityDto.setFilePath(userPath);
                fileEntityDto.setFileName(file.getName());
                fileEntityDto.setFileType(String.valueOf(file.getType()));
                if (file.getType() != 1) {
                    fileEntityDto.setFileSize(GetFileSize(file));
                } else {
                    fileEntityDto.setFileSize(GetFileSizes(sumSzie));
                }
                fileEntityDto.setUpDate(DateUtils.formatDate(file.getTimestamp().getTime(), "yyyy-MM-dd HH:mm:ss"));
                list.add(fileEntityDto);
            }
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            ftpClientFactory.destroyClient(ftp);
        }
        resp = new BaseResp(CommonEnum.SUCCESS, list);
        return resp;
    }

    /**
     * 获取用户FPT已用空间大小
     *
     * @param path
     * @return
     */
    public static BaseResp getFtpFileSize(String path) {
        BaseResp resp = null;
        Long userSize = 0L;
        FTPClient ftp = null;
        TreeVo vo = new TreeVo("tools", 0L);
        try {
            ftp = ftpClientFactory.makeFtpClient();
            ftp.setControlEncoding("UTF-8");
            if (!ftp.changeWorkingDirectory(path)) {
                resp = new BaseResp(CommonEnum.FILE_NO_EXITIS);
                resp.setMessage("该文件夹不存在,请检查!");
                return resp;
            }
            String dirPath = path;
            FTPFile[] ftpFile = null;
            List<String> dirName = new ArrayList<>();
            ftpFile = ftp.listFiles(dirPath);
            vo = recursionTree(ftpFile, ftp, vo);
            List<TreeVo> children = vo.getChildren();

            log.info("userSzies={}", vo.getSize());
        } catch (Exception e) {
            log.error(Atom.ERROR_MSG, "ftp连接出错:" + e.getMessage());
        } finally {
            ftpClientFactory.destroyClient(ftp);
        }
        resp = new BaseResp(CommonEnum.SUCCESS, vo.getSize());
        return resp;
    }


    /***
     * 循环进入目录获取size
     * @param ftp
     * @param dirName
     * @param path 原始路径
     * @return
     */
    public static boolean getSize(FTPClient ftp, String path, List<String> dirName) {
        log.info("根目录地址:" + path);
        Long size = 0L;
        List<String> fileList = new ArrayList<>();
        try {
            //进入目录
            Iterator it = dirName.iterator();
            while (it.hasNext()) {
                String newDirPath = null;
                String name = it.next().toString();
                String paths = path + "/" + name;
                log.info("遍历文件名得到的新目录:" + paths);
                if (ftp.changeWorkingDirectory(paths)) {
                    FTPFile[] files = ftp.listFiles(paths);
                    if (files.length != 0) {
                        //再去里面查!给我查!
                        for (FTPFile file : files) {
                            if (file.getType() == 1) {
                                fileList.add(file.getName());
                                newDirPath = paths;
                                log.info("文件夹下还存在文件夹的地址:" + newDirPath);
                                getSize(ftp, newDirPath, fileList);

                            } else {
                                //不记录文件夹的Size
                                size += file.getSize();
                                userSizes = size;
                                log.info("size={}", userSizes);
                            }

                        }
                    }
                } else {
                    return false;
                }
            }
        } catch (IOException e) {
            log.error(e.toString());
        }
        return true;
    }


    //重命名文件或者文件夹 需要路径,需要原名称和新名称,新名称是文件 则要加后缀
    public static boolean reName(String path, String from, String to) {
        FTPClient ftp = null;
        try {
            ftp = ftpClientFactory.makeFtpClient();
            //进入path
            if (!ftp.changeWorkingDirectory(new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
                return false;
            }

            //获取最后一个.的位置
            int lastIndexOf = from.lastIndexOf(".");
            String newFileNma = to;
            //-1说明是文件夹没有后缀
//            if (lastIndexOf != -1) {
//                String suffix = from.substring(lastIndexOf);
//                newFileNma = to + suffix;
//            } else newFileNma = to;
            if (!ftp.rename(from, new String(newFileNma.getBytes("UTF-8"),
                    DEFAULT_ENCODING))) {
                return false;
            }
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            ftpClientFactory.destroyClient(ftp);
        }
        return true;
    }

    /**
     * 上传文件到FTP 支持中文
     *
     * @param inputStream
     * @param path
     * @param fileNmae
     * @return
     */
    public static BaseResp upload(InputStream inputStream, String path, String fileNmae) {
        BaseResp baseResp = null;
        log.info("上传文件开始");
        log.info("path={]", path);
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientFactory.makeFtpClient();
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.setDataTimeout(60000);
            if (!ftpClient.changeWorkingDirectory(new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
                return baseResp = new BaseResp(CommonEnum.DIR_IS_NOT_EXITIS);
            }
            try {
                ftpClient.storeFile(new String(fileNmae.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING), inputStream);
                String filePath = new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
                String file = new String(fileNmae.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
                FTPFile[] files = ftpClient.listFiles(filePath + "/" + file);
                if (files.length > 0) {
                    baseResp = new BaseResp(CommonEnum.SUCCESS);
                    baseResp.setMessage("文件上传成功!");
                } else {
                    baseResp = new BaseResp(CommonEnum.UPLOAD_FILE_ERROR);
                    baseResp.setMessage("文件上传失败!");
                }
            } catch (IOException e) {
                log.error(e.toString());
            }
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            ftpClientFactory.destroyClient(ftpClient);
        }
        return baseResp;
    }

    /**
     * FTP下载单个文件测试
     */
    public static BaseResp downloadFtpFile(
            String ftpPath,
            String uploadFileName,
            HttpServletResponse response) {
        boolean bn = false;
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientFactory.makeFtpClient();
            // 设置文件ContentType类型,这样设置,会自动判断下载文件类型
            response.setContentType("applicatoin/octet-stream");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            String filesName = URLEncoder.encode(uploadFileName, StandardCharsets.UTF_8);
            filesName = URLEncoder.encode(uploadFileName, "UTF-8");
            response.setHeader(
                    "Content-Disposition",
                    "attachment;filename=" + java.net.URLDecoder.decode(filesName, "UTF-8"));
            response.setHeader("Cache-Control", "no-cache");
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            int reply = ftpClient.getReplyCode();
            // 切换到ftp的服务器路径
            if (!ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
                return new BaseResp(CommonEnum.FILE_NO_EXITIS);
            }
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                throw new IOException("failed to connect to the FTP Server");
            }
            // 此句代码适用Linux的FTP服务器
            String newPath = new String(uploadFileName.getBytes("UTF-8"), DEFAULT_ENCODING);
            OutputStream out = response.getOutputStream();
            InputStream in = ftpClient.retrieveFileStream(newPath);
            BufferedInputStream bis = new BufferedInputStream(in);
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = bis.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            bis.close();
            in.close();
            out.flush();
            return new BaseResp(CommonEnum.SUCCESS);

        } catch (FTPConnectionClosedException e) {
            log.error("ftp连接被关闭!ERROR={}", e.getMessage());
            throw new BizException(-1, e.getMessage());
        } catch (Exception e) {
            log.error("ERR : upload file " + uploadFileName + " from ftp : failed!", e.getMessage());
            throw new BizException(-1, e.getMessage());
        }
    }


    public static String GetFileSize(FTPFile file) {
        String size = "";
        long fileS = file.getSize();
        DecimalFormat df = new DecimalFormat("#.00");
        if (fileS < 1024) {
            size = df.format((double) fileS) + "BT";
        } else if (fileS < 1048576) {
            size = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            size = df.format((double) fileS / 1048576) + "MB";
        } else {
            size = df.format((double) fileS / 1073741824) + "GB";
        }
        return size;
    }

    //转换占用内存
    public static String GetFileSizes(Long sumSzie) {
        String size = "";
        long fileS = sumSzie;
        DecimalFormat df = new DecimalFormat("#.00");
        if (fileS < 1024) {
            size = df.format((double) fileS) + "BT";
        } else if (fileS < 1048576) {
            size = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            size = df.format((double) fileS / 1048576) + "MB";
        } else {
            size = df.format((double) fileS / 1073741824) + "GB";
        }
        return size;
    }

   /* public static void getst(FTPClient ftpClient, String path) throws IOException {
        try {
            ftpClient = ftpClientFactory.makeFtpClient();

            // 如果ftp连接成功,需要验证路径是否存在
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setControlEncoding("UTF-8");
            // 获取根目录文件
            FTPFile[] files = ftpClient.listFiles(path);
            // 创建根节点
            TreeVo root = new TreeVo("tools", 0L);
            if (files.length > 0) {
                try {
                    recursionTree(files, ftpClient, root);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } catch (SocketException e) {
        } catch (IOException e) {
            e.printStackTrace();
            log.info("FTP的端口错误,请正确配置。");
        } catch (Exception e) {
            e.printStackTrace();
            log.info("查询数据失败。");
        }

    }*/

    /**
     * 递归获取ftp文件目录树
     *
     * @param files
     * @param ftpClient
     * @param pTree
     * @return
     * @throws IOException
     */
    public static TreeVo recursionTree(FTPFile[] files, FTPClient ftpClient, TreeVo pTree) throws IOException {
        Long size = 0L;
        for (FTPFile file : files) {
            if (file.isDirectory()) {
                // new String(file.getName().getBytes("UTF-8"),"iso-8859-1")为了将目录名的编码转成FTPClient需要的编码,否则切换目录会失败。
                boolean flag = ftpClient.changeWorkingDirectory(new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
                files = ftpClient.listFiles();
                if (files.length > 0) {
                    pTree.getChildren().add(recursionTree(files, ftpClient, new TreeVo(file.getName(), file.getSize())));
                } else {
                    pTree.getChildren().add(new TreeVo(file.getName(), file.getSize()));
                }

            } else {
                log.info(file.getName() + ":文件大小为:" + file.getSize());
                size += file.getSize();
                log.info("size={}", size.toString());
                userSizes += file.getSize();
                pTree.setSize(size);
                pTree.getChildren().add(new TreeVo(file.getName(), file.getSize()));
            }
        }
        // 子文件夹遍历完成后返回上级目录
        ftpClient.changeToParentDirectory();
        return pTree;
    }

    //视频截图 并生成文件夹存放文件
    public static BaseResp screenshots(String seconds, List<String> fileName, String path, String ffmpegUrl) {
        BaseResp baseResp;
        log.info("进入FTP处理视频截图");
        log.info("fileName={}", ToStringBuilder.reflectionToString(fileName, ToStringStyle.MULTI_LINE_STYLE));
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientFactory.makeFtpClient();
            ftpClient.setControlEncoding("UTF-8");
            path = new String(path.getBytes("UTF-8"), DEFAULT_ENCODING);
            //进入路径
            if (ftpClient.changeWorkingDirectory(path)) {
                Iterator it = fileName.iterator();
                while (it.hasNext()) {
                    String videoName = (String) it.next();
                    videoName = new String(videoName.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
                    FTPFile[] file = ftpClient.listFiles(path + "/" + videoName);

                    if (file.length != 0) {
                        for (FTPFile ftpFile : file) {
                            String absolutePath = videoName;
                            String name = ftpFile.getName();
                            String oldDir = absolutePath;
                            String time = DateUtil.getTimeStrBySecond(Integer.valueOf(seconds));
                            String outName = path + "/" + System.currentTimeMillis() + "Screenshots";
                            CreateDirecroty(outName, path);
                            String size = "1920x1080";
                            FfmpegUtils.covPic(oldDir, time, outName, size);
                        }
                    } else {
                        continue;
                    }
                }

            } else {
                baseResp = new BaseResp(CommonEnum.DIR_IS_NOT_EXITIS);
                return baseResp;
            }


        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            ftpClientFactory.destroyClient(ftpClient);
        }


        return null;

    }

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值