JAVA FTPClient文件操作

创建/关闭连接

import com.gallery.constants.FtpConstants;
import com.gallery.framework.api.ErrorStatusEnum;
import com.gallery.framework.exception.BizException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

import java.io.IOException;

/**
 * @Author: Yilia
 * @Date: 2022/5/6/0006 14:42
 */

public class FtpUtils {
    protected final static Logger logger = Logger.getLogger(FtpUtils.class);

    /**
     * 创建ftp连接
     * @return
     * @throws IOException
     */
    public static FTPClient getFTPClient() throws IOException {
        //创建ftp客户端
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");
        //链接ftp服务器
        ftpClient.connect(FtpConstants.HOSTNAME, FtpConstants.PORT);
        // 修改连接模式 服务器需要使用被动模式
        ftpClient.enterLocalPassiveMode();
        //登录ftp
        ftpClient.login(FtpConstants.USERNAME, FtpConstants.PASSWORD);
        int  reply = ftpClient.getReplyCode();
        //如果reply返回230就算成功了,如果返回530密码用户名错误或当前用户无权限下面有详细的解释。
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
            throw new BizException(ErrorStatusEnum.RESOURCE_IN_USE.getCode(), "ftp连接失败");
        }
        return ftpClient;
    }

    /**
     * 关闭FTP方法
     * @param ftp
     * @return
     */
    public static void closeFTP(FTPClient ftp){
        try {
            ftp.logout();
        } catch (Exception e) {
            logger.error("FTP关闭失败");
        }finally{
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    logger.error("FTP关闭失败");
                }
            }
        }
    }

}

文件上传

    public void uploadFile(MultipartFile file, String toPath, String fileName) throws IOException {
        FTPClient ftpClient = FtpUtils.getFTPClient();
        // 设置PassiveMode传输
        ftpClient.enterLocalPassiveMode();
        //设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        ftpClient.changeWorkingDirectory(toPath);

        ftpClient.storeFile(fileName, file.getInputStream());
        FtpUtils.closeFTP(ftpClient);
    }

文件下载

    /**
     * 文件下载
     * @param response
     * @param fromPath 下载路径
     * @param fileName 下载文件名
     * @throws IOException
     */
    public void downloadFileOption(HttpServletResponse response, String fromPath, String fileName) throws IOException {
        OutputStream outputStream = null;
        FTPClient ftpClient = FtpUtils.getFTPClient();
        // 设置PassiveMode传输
        ftpClient.enterLocalPassiveMode();
        ftpClient.changeWorkingDirectory(fromPath);

        FTPFile[] files = ftpClient.listFiles();
        for (FTPFile file : files) {
            // 取得指定文件并下载
            if (file.getName().equals(fileName)) {
                outputStream = response.getOutputStream();
                boolean flag = ftpClient.retrieveFile(file.getName(), outputStream);
                outputStream.flush();
                outputStream.close();
                
                if (!flag) {
                    logger.info("文件下载失败");
                }
            }
        }
        FtpUtils.closeFTP(ftpClient);
    }

文件复制粘贴

/**
     * 文件粘贴操作
     * @param fromPath 文件所在路径
     * @param toPath 粘贴目的所在路径
     * @param fileName 文件名
     * @param directory 是否文件夹
     * @param option 拷贝/剪切
     * @throws IOException
     */
    public void pasteFileOperation(String fromPath, String toPath, String fileName, boolean directory, String option) throws IOException {
        FTPClient ftpClient = FtpUtils.getFTPClient();
        if (directory) {
            // 目标路径下新建目录
            fromPath = fromPath + fileName + "/";
            ftpClient.changeWorkingDirectory(toPath);
            ftpClient.makeDirectory(fileName);
            toPath = toPath + fileName + "/";
            dealDirectory(ftpClient, fromPath, toPath, option);
        }else {
            // 文件
            // 跳转到文件目录
            ftpClient.changeWorkingDirectory(fromPath);
            boolean flag = false;
            if (FILE_OPTION_COPY.equals(option)) {
                // 复制
                flag = copyFile(ftpClient, fileName, toPath);
            }
            if (FILE_OPTION_CUT.equals(option)) {
                // 剪切
                flag = ftpClient.rename(fromPath + fileName, toPath + fileName);
            }

            if(!flag){
                logger.info("文件粘贴失败");
            }
        }
        FtpUtils.closeFTP(ftpClient);
    }

    /**
     * 文件夹处理
     * @param ftpClient
     * @param fromPath
     * @param toPath
     * @param option
     * @throws IOException
     */
    private void dealDirectory(FTPClient ftpClient, String fromPath, String toPath, String option) throws IOException {
        // 进入原目录进行获取文件列表
        ftpClient.changeWorkingDirectory(fromPath);
        FTPFile[] ftpFiles = ftpClient.listFiles();
        for (FTPFile ftpFile : ftpFiles) {
            if (ftpFile.isDirectory()) {
                // 目录
                // 切换粘贴位置
                ftpClient.changeWorkingDirectory(toPath);
                // 复制目录
                if (!ftpClient.makeDirectory(ftpFile.getName())) {
                    FtpUtils.closeFTP(ftpClient);
                    logger.error("目录复制失败");
                }
                dealDirectory(ftpClient, fromPath + ftpFile.getName() + "/", toPath + ftpFile.getName() + "/", option);
            }else {
                // 文件
                // 进入原目录进行复制操作
                ftpClient.changeWorkingDirectory(fromPath);
                boolean flag = false;
                if (FILE_OPTION_COPY.equals(option)) {
                    // 复制
                    flag = copyFile(ftpClient, ftpFile.getName(), toPath);
                }
                if (FILE_OPTION_CUT.equals(option)) {
                    // 剪切
                    flag = ftpClient.rename(fromPath + ftpFile.getName(), toPath + ftpFile.getName());
                }

                if(!flag){
                    FtpUtils.closeFTP(ftpClient);
                    logger.error("文件粘贴失败");
                }
            }
        }

        ftpClient.changeWorkingDirectory(fromPath);
        if (FILE_OPTION_CUT.equals(option) && ftpClient.listFiles().length == 0) {
            // 剪切
            boolean flag = ftpClient.removeDirectory(fromPath);
            if(!flag){
                FtpUtils.closeFTP(ftpClient);
                logger.error("文件粘贴失败");
            }
        }
    }
    
    /**
     * 复制文件到指定位置
     * @param ftpClient
     * @param fileName 文件名
     * @param toPath 目标路径
     * @return
     * @throws IOException
     */
    private boolean copyFile(FTPClient ftpClient, String fileName, String toPath) throws IOException {
        //读取文件,使用下载文件的方法把文件写入内存,绑定到out流上
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ftpClient.retrieveFile(new String(fileName.getBytes("UTF-8"),"ISO-8859-1"), out);
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        //文件复制,先读,再写
        //二进制
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        boolean fileState = ftpClient.storeFile(toPath + (new String(fileName.getBytes("UTF-8"), "ISO-8859-1")), in);
        out.flush();
        out.close();
        in.close();
        return fileState;
    }

文件删除

    /**
     * 删除文件操作
     * @param fromPath 文件所在路径
     * @param fileName 文件名
     * @param directory 是否目录
     * @throws IOException
     */
    public void deleteFileOperation(String fromPath, String fileName, boolean directory) throws IOException {
        FTPClient ftpClient = FtpUtils.getFTPClient();
        ftpClient.changeWorkingDirectory(fromPath);
        if (directory) {
            deleteDirectory(ftpClient, fromPath + fileName + "/");
        }else {
            if(!ftpClient.deleteFile(fileName)){
                logger.error("删除文件失败");
            }
        }
        FtpUtils.closeFTP(ftpClient);
    }

    /**
     * 删除文件夹
     * @param ftpClient
     * @param fromPath
     * @throws Exception
     */
    private void deleteDirectory(FTPClient ftpClient, String fromPath) throws IOException {
        // 进入原目录进行获取文件列表
        ftpClient.changeWorkingDirectory(fromPath);
        FTPFile[] ftpFiles = ftpClient.listFiles();
        for (FTPFile ftpFile : ftpFiles) {
            if (ftpFile.isDirectory()) {
                // 目录
                deleteDirectory(ftpClient, fromPath + ftpFile.getName() + "/");
            } else {
                // 文件
                // 进入原目录进行删除操作
                ftpClient.changeWorkingDirectory(fromPath);
                if(!ftpClient.deleteFile(ftpFile.getName())){
                    FtpUtils.closeFTP(ftpClient);
                    logger.error("文件删除失败");
                }
            }
        }

        ftpClient.changeWorkingDirectory(fromPath);
        if (ftpClient.listFiles().length == 0) {
            // 删除文件夹
            if(!ftpClient.removeDirectory(fromPath)){
                FtpUtils.closeFTP(ftpClient);
                logger.error("文件删除失败");
            }
        }
    }

压缩文件

    /**
     * 压缩文件操作
     * @param fromPath 文件所在路径
     * @param fileName 文件名称
     * @param toPath 压缩后的路径
     * @param compressName 压缩后的名称
     * @param format 压缩格式 tar.gz/zip/rar
     * @throws IOException
     */
    public void compressFileOperation(String fromPath, String fileName, String toPath, String compressName, String format) throws IOException {
        // 拼接文件完整路径
        String fromFile = ROOT_PATH + fromPath + fileName;
        String cachePath = FILE_CACHE + fileName + "." + format;
        File sourceFile = new File(fromFile);

        // 压缩文件
        FileOutputStream fileOutputStream = new FileOutputStream(cachePath);
        if (FILE_COMPRESS_GZ.equals(format)) {
            GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new BufferedOutputStream(fileOutputStream));
            TarArchiveOutputStream tarArchive = new TarArchiveOutputStream(gzipOutputStream);
            // 使文件名支持超过 100 个字节
            tarArchive.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
            compressTarGZ(sourceFile, fileName, tarArchive);
            tarArchive.close();
            gzipOutputStream.close();

        }else if (FILE_COMPRESS_ZIP.equals(format) || FILE_COMPRESS_RAR.equals(format)) {
            ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
            compressZip(sourceFile, fileName, zipOutputStream);
            zipOutputStream.flush();
            zipOutputStream.close();
        }
        fileOutputStream.close();

        // 上传到ftp
        FTPClient ftpClient = FtpUtils.getFTPClient();
        // 设置PassiveMode传输
        ftpClient.enterLocalPassiveMode();
        //设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        ftpClient.changeWorkingDirectory(toPath);
        FileInputStream fileInputStream = new FileInputStream(new File(cachePath));
        boolean flag = ftpClient.storeFile(compressName, fileInputStream);
        if(!flag){
            logger.error("压缩文件失败");
        }

        fileInputStream.close();
        FtpUtils.closeFTP(ftpClient);

        // 删除临时文件
        File cacheFile = new File(cachePath);
        if (cacheFile.exists()) {
            boolean delete = cacheFile.delete();
            if (!delete) {
                logger.error("BizException:压缩缓存文件删除失败");
            }
        }
    }

    /**
     * 压缩成gz格式文件
     * @param sourceFile
     * @param fileName
     * @param tarArchive
     * @throws IOException
     */
    private void compressTarGZ(File sourceFile, String fileName, TarArchiveOutputStream tarArchive) throws IOException {
        tarArchive.putArchiveEntry(new TarArchiveEntry(sourceFile, fileName));
        if (sourceFile.isDirectory()) {
            // 目录
            tarArchive.closeArchiveEntry();
            // 遍历文件夹下的文件
            for (File file : sourceFile.listFiles()) {
                // 递归遍历文件目录树
                compressTarGZ(file, fileName + "\\" + file.getName(), tarArchive);
            }
        }else if (sourceFile.isFile()) {
            // 文件
            FileInputStream fileInputStream = null;
            BufferedInputStream bufferedInputStream = null;
            try {
                fileInputStream = new FileInputStream(sourceFile);
                bufferedInputStream = new BufferedInputStream(fileInputStream);
                // 写入文件
                IOUtils.copy(bufferedInputStream, tarArchive);
                tarArchive.closeArchiveEntry();
            } catch (IOException e) {
                logger.error("IOException:" + e);
            }finally {
                try {
                    if (null != bufferedInputStream) {
                        bufferedInputStream.close();
                    }
                    if (null != fileInputStream) {
                        fileInputStream.close();
                    }
                }catch (IOException e) {
                    logger.error("IOException:" + e);
                }
            }
        }
    }

    /**
     * 压缩成zip格式文件
     * @param sourceFile
     * @param fileName
     * @param zipOutputStream
     * @throws IOException
     */
    private void compressZip(File sourceFile, String fileName, ZipOutputStream zipOutputStream) throws IOException {
        if (sourceFile.isDirectory()) {
            // 目录
            // 目录创建要带斜杠 否则会创建文件
            zipOutputStream.putNextEntry(new ZipEntry(fileName + "/"));
            // 遍历文件夹下的文件
            for (File file : sourceFile.listFiles()) {
                // 递归遍历文件目录树
                compressZip(file, fileName + "/" + file.getName(), zipOutputStream);
            }
        }else if (sourceFile.isFile()) {
            // 文件
            zipOutputStream.putNextEntry(new ZipEntry(fileName));
            FileInputStream in = null;
            try {
                in = new FileInputStream(sourceFile);
                byte[] bytes = new byte[1024];
                int num = -1;
                while ((num = in.read(bytes, 0, bytes.length)) != -1) {
                    zipOutputStream.write(bytes, 0, num);
                }
            } catch (IOException e) {
                logger.error("IOException:" + e);
            }finally {
                if (null != in) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        logger.error("IOException:" + e);
                    }
                }
            }
        }
    }

解压文件

    /**
     * 解压文件操作
     * @param fromPath 文件所在路径
     * @param fileName 文件名
     * @param toPath 解压到路径
     * @param format 压缩格式 tar.gz/zip/rar
     * @throws IOException
     */
    public void decompressFileOperation(String fromPath, String fileName, String toPath, String format) throws IOException {
        String cachePath = FILE_CACHE + fileName;
        FTPClient ftpClient = FtpUtils.getFTPClient();
        // 设置PassiveMode传输
        ftpClient.enterLocalPassiveMode();
        //设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        ftpClient.changeWorkingDirectory(fromPath);

        // 获取压缩文件
        OutputStream outputStream = new FileOutputStream(new File(cachePath));
        ftpClient.retrieveFile(fileName, outputStream);
        outputStream.close();

        if (FILE_COMPRESS_GZ.equals(format)) {
            // tar.gz
            decompressionGz(ftpClient, cachePath, toPath);
        }else if (FILE_COMPRESS_ZIP.equals(format) || FILE_COMPRESS_RAR.equals(format)) {
            // zip/rar
            decompressionZip(ftpClient, cachePath, toPath);
        }
        FtpUtils.closeFTP(ftpClient);

        // 删除临时文件
        File file = new File(cachePath);
        if (file.exists()) {
            boolean delete = file.delete();
            if (!delete) {
                logger.error("删除缓存文件失败");
            }
        }
    }

    /**
     * 解压gz文件
     * @param ftpClient
     * @param cachePath
     * @param toPath
     */
    private void decompressionGz(FTPClient ftpClient, String cachePath, String toPath) throws IOException {
        InputStream inputStream = new FileInputStream(cachePath);
        GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
        TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipInputStream);
        TarArchiveEntry tarArchiveEntry = null;
        
        while( (tarArchiveEntry = tarArchiveInputStream.getNextTarEntry()) != null ){
            String entryName = tarArchiveEntry.getName();

            if(tarArchiveEntry.isDirectory()){
                // 目录
                // 设置PassiveMode传输
                ftpClient.enterLocalPassiveMode();
                //设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.changeWorkingDirectory(toPath);
                // 创建文件夹
                ftpClient.makeDirectory(entryName);
                ftpClient.changeWorkingDirectory(entryName);
            }else{
                //文件
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                //读取文件,使用下载文件的方法把文件写入内存,绑定到out流上
                byte[] array = new byte[1024];
                int num = -1;
                while ((num = tarArchiveInputStream.read(array, 0, array.length)) != -1) {
                    out.write(array, 0, num);
                }

                ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

                // 设置PassiveMode传输
                ftpClient.enterLocalPassiveMode();
                //设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.changeWorkingDirectory(toPath);
                ftpClient.storeFile(entryName, in);
                out.flush();
                out.close();
                in.close();
            }
        }
        
        tarArchiveInputStream.close();
        gzipInputStream.close();
        inputStream.close();
    }

    /**
     * 解压zip、rar文件
     * @param ftpClient
     * @param cachePath
     * @param toPath
     */
    private void decompressionZip(FTPClient ftpClient, String cachePath, String toPath) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(cachePath);
        ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
        ZipEntry zipEntry = null;

        while( (zipEntry = zipInputStream.getNextEntry()) != null ){
            String entryName = zipEntry.getName();

            if(zipEntry.isDirectory()){
                // 目录
                // 设置PassiveMode传输
                ftpClient.enterLocalPassiveMode();
                //设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.changeWorkingDirectory(toPath);
                // 创建文件夹
                ftpClient.makeDirectory(entryName);
                ftpClient.changeWorkingDirectory(entryName);
            }else{
                //文件
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                //读取文件,使用下载文件的方法把文件写入内存,绑定到out流上
                byte[] array = new byte[1024];
                int num = -1;
                while ((num = zipInputStream.read(array, 0, array.length)) != -1) {
                    out.write(array, 0, num);
                }

                ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

                // 设置PassiveMode传输
                ftpClient.enterLocalPassiveMode();
                // 设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.changeWorkingDirectory(toPath);
                // 创建文件
                ftpClient.storeFile(entryName, in);
                out.flush();
                out.close();
                in.close();
            }
        }
        zipInputStream.close();
        fileInputStream.close();
    }

ftp日志打印

import java.io.OutputStream;
import org.apache.log4j.Logger;

public class LogOutputStream extends OutputStream {
    private final Logger logger;
    /** The internal memory for the written bytes. */
    private StringBuffer mem;

    public LogOutputStream(final Logger logger) {
        this.logger = logger;
        mem = new StringBuffer();
    }

    @Override
    public void write(final int b) {
        if ( (char) b == '\n' ) {
            flush();
            return;
        }
        mem = mem.append((char)b);
    }

    @Override
    public void flush() {
        logger.info(mem.toString());
        mem = new StringBuffer();
    }
}

protected final static Logger logger = Logger.getLogger(FtpUtils.class);

// 打印ftp日志
ftpClient.addProtocolCommandListener(
    new PrintCommandListener(
        new PrintWriter(new OutputStreamWriter(new LogOutputStream(logger), "UTF-8")), true));

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值