FTPClientHelper.java 10.2 KB
package com.viontech.ftp;

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

import java.io.*;

/**
 * ftp客户端辅助bean
 */
@Slf4j
public class FTPClientHelper {

    private FTPClientPool ftpClientPool;

    private String tempPath;

    private int retryCount = 3;

    public void setFtpClientPool(FTPClientPool ftpClientPool) {
        this.ftpClientPool = ftpClientPool;
    }

    /**
     * 下载 remote文件流
     *
     * @param remote 远程文件
     *
     * @return 字节数据
     */
    public byte[] retrieveFileStream(String remote) {
        FTPClient client = null;
        ByteArrayOutputStream out = null;

        try {
            log.info("开始获取FTPClient对象");
            client = ftpClientPool.borrowObject();
            log.info("结束获取FTPClient对象");
            out = new ByteArrayOutputStream();
            log.info("开始获取文件");
            boolean result = client.retrieveFile(remote, out);
            log.info("结束获取文件" + result);
            if (result) {
                return out.toByteArray();
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("下载文件失败", e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            ftpClientPool.returnObject(client);

        }
        return null;

    }


    /**
     * 创建目录    单个不可递归
     *
     * @param pathname 目录名称
     *
     * @return
     */
    public boolean makeDirectory(String pathname) throws Exception {
        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            return client.makeDirectory(pathname);
        } finally {
            ftpClientPool.returnObject(client);
        }
    }

    /**
     * 删除目录,单个不可递归
     *
     * @param pathname
     *
     * @return
     */
    public boolean removeDirectory(String pathname) throws Exception {
        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            return client.removeDirectory(pathname);
        } finally {
            ftpClientPool.returnObject(client);
        }
    }

    /**
     * 删除文件 单个 ,不可递归
     *
     * @param pathname
     *
     * @return
     */
    public boolean deleteFile(String pathname) throws Exception {

        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            return client.deleteFile(pathname);
        } finally {
            ftpClientPool.returnObject(client);
        }
    }

    /**
     * 上传文件
     *
     * @param remote
     * @param local
     *
     * @return
     */
    public boolean storeFile(String remote, InputStream local) {
        Exception throwException = null;
        for (int i = 0; i < retryCount; i++) { // 尝试三次 如果三次不成功那么存储到本地
            FTPClient client = null;
            try {
                client = ftpClientPool.borrowObject();
                boolean result = client.storeFile(remote, local);
                if (result) {
                    return result;
                }
            } catch (Exception e) {
                e.printStackTrace();
                throwException = e;
            } finally {
                if (local != null) {
                    try {
                        local.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                ftpClientPool.returnObject(client);
            }
        }
        log.error("通过ftp存储文件" + remote + "时发生异常 ,开始尝试存储到本地路径" + tempPath + "下", throwException);
        return storeTemp(remote, local);
    }

    public boolean isExist(String remote) {
        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
            int count = client.list(remote);
            if (count == 0) {
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ftpClientPool.returnObject(client);
        }
        return false;

    }

    public boolean storeFile(String remote, byte[] content) {
        Exception throwException = null;
        for (int i = 0; i < retryCount; i++) { // 尝试三次 如果三次不成功那么存储到本地
            Long startTime = System.currentTimeMillis();
            FTPClient client = null;
            ByteArrayInputStream bis = null;
            try {
                client = ftpClientPool.borrowObject();
                String parentPath = getParentPath(remote);
                boolean makeDirectoryResult = client.makeDirectory(parentPath);
                if (!makeDirectoryResult) {//如果创建失败 可能是不支持一次创建多级目录
                    makeDirectorys(client, parentPath);
                }

                bis = new ByteArrayInputStream(content);
                boolean result = client.storeFile(remote, bis);
                if (result) {
                    return result;
                } else {
                    log.error("通过ftp存储文件" + remote + "时未发生异常 ,但存储失败");
                    return result;
                }
            } catch (Exception e) {
                e.printStackTrace();
                throwException = e;
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                ftpClientPool.returnObject(client);
                Long endTime = System.currentTimeMillis();

            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        log.error("通过ftp存储文件" + remote + "时发生异常 ,开始尝试存储到本地路径" + tempPath + "下", throwException);
        return storeTemp(remote, content);

    }

    private boolean makeDirectorys(FTPClient ftpclient, String remote) throws Exception {
        File file = new File(remote);
        if (!file.getPath().contains(File.separator)) { 
            ftpclient.makeDirectory(file.getPath());
        } else {
            makeDirectorys(ftpclient, file.getParent());
            ftpclient.makeDirectory(file.getPath());
        }
        return true;
    }

    private boolean storeTemp(String remote, InputStream local) {

        FileOutputStream fos = null;
        try {
            File file = new File(tempPath, remote);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            fos = new FileOutputStream(file);
            int bytesWritten = 0;
            int byteCount = 0;
            byte[] bytes = new byte[1024];
            while ((byteCount = local.read(bytes)) != -1) {
                fos.write(bytes, bytesWritten, byteCount);
                bytesWritten += byteCount;
            }

            return true;
        } catch (Exception e) {
            log.error("存储到本地路径" + tempPath + "下失败", e);
            e.printStackTrace();

        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (local != null) {
                    local.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private boolean storeTemp(String remote, byte[] content) {
        FileOutputStream fos = null;
        try {
            File file = new File(tempPath, remote);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            fos = new FileOutputStream(file);
            fos.write(content);
            fos.flush();
            return true;
        } catch (Exception e) {
            log.error("存储到本地路径" + tempPath + "下失败", e);
            e.printStackTrace();

        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public InputStream getInputStream(FileInputStream fileInput) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * 4];
        int n = -1;
        InputStream inputStream = null;
        try {
            while ((n = fileInput.read(buffer)) != -1) {
                baos.write(buffer, 0, n);
            }
            byte[] byteArray = baos.toByteArray();
            inputStream = new ByteArrayInputStream(byteArray);
            return inputStream;


        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private String getParentPath(String remote) {
        File f = new File(remote);
        return f.getParent();
    }


    public String getTempPath() {
        return tempPath;
    }

    public void setTempPath(String tempPath) {
        this.tempPath = tempPath;
    }

    public boolean deleteItem(String remote) {
        FTPClient client = null;
        try {
            client = ftpClientPool.borrowObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        boolean isDelete = false;
        try {
            isDelete = client.deleteFile(remote);
        } catch (IOException e) {
            e.printStackTrace();
        }
        ftpClientPool.returnObject(client);
        return isDelete;
    }
}