ftp与sftp工具类

发布时间 2023-08-04 15:32:58作者: 大山008

1、ftp、ftps、sftp的区别

https://www.cnblogs.com/Javi/p/6904587.html

2、ftp

package com.zhhs.common.utils.ftp;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.tomcat.util.http.fileupload.FileItem;

import java.io.*;

/**
 * FTP工具类
 * 文件上传
 * 文件下载
 */
@Slf4j
public class FtpUtil {

    /**
     * 设置缓冲区大小4M
     **/
    private static final int BUFFER_SIZE = 1024 * 1024 * 4;

    /**
     * 本地字符编码
     **/
    private static String LOCAL_CHARSET = "GBK";

    /**
     * UTF-8字符编码
     **/
    private static final String CHARSET_UTF8 = "UTF-8";

    /**
     * OPTS UTF8字符串常量
     **/
    private static final String OPTS_UTF8 = "OPTS UTF8";

    /**
     * FTP协议里面,规定文件名编码为iso-8859-1
     **/
    private static final String SERVER_CHARSET = "ISO-8859-1";

    /**
     * 连接FTP服务器
     */
    private static FTPClient login(String host, Integer port, String username, String password) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(host, port);
            ftpClient.login(username, password);
            ftpClient.setBufferSize(BUFFER_SIZE);
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                closeConnect(ftpClient);
            }
            return ftpClient;
        } catch (Exception e) {
            log.error("",e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭FTP连接
     */
    private static void closeConnect(FTPClient ftpClient) {
        if (ftpClient != null && ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException e) {
                log.error("",e);
            }
        }
    }

    /**
     * FTP服务器路径编码转换
     *
     * @param ftpPath FTP服务器路径
     * @return String
     */
    private static String changeEncoding(FTPClient ftpClient,String ftpPath) {
        String directory = null;
        try {
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(OPTS_UTF8, "ON"))) {
                LOCAL_CHARSET = CHARSET_UTF8;
            }
            directory = new String(ftpPath.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
        } catch (Exception e) {
            log.error("",e);
        }
        return directory;
    }

    /**
     * 改变工作目录
     * 如果没有,则创建工作目录
     * @param path
     */
    private static void changeAndMakeWorkingDir(FTPClient ftpClient,String path) {
        try {
            ftpClient.changeWorkingDirectory("/");
            path = path.replaceAll("\\\\","/");
            String[] path_array = path.split("/");
            for (String s : path_array) {
                boolean b = ftpClient.changeWorkingDirectory(s);
                if (!b) {
                    ftpClient.makeDirectory(s);
                    ftpClient.changeWorkingDirectory(s);
                }
            }
        } catch (IOException e) {
            log.error("",e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 上传
     * @param ftpClient
     * @param filename
     * @param dirPath
     * @param in
     * @return
     */
    public static boolean upload (FTPClient ftpClient, String filename, String dirPath, InputStream in) {
        if (!ftpClient.isConnected()) {
            return false;
        }
        boolean isSuccess = false;

        if (ftpClient != null) {
            try {
                if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(OPTS_UTF8, "ON"))) {
                    LOCAL_CHARSET = CHARSET_UTF8;
                }
                ftpClient.setControlEncoding(LOCAL_CHARSET);
                String path = changeEncoding(ftpClient,dirPath);

                changeAndMakeWorkingDir(ftpClient,path);
                isSuccess = ftpClient.storeFile(new String(filename.getBytes(), SERVER_CHARSET), in);
            } catch (Exception e) {
                log.error("",e);
            } finally {
                if (in != null){
                    try{
                        in.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
            }
        }
        return isSuccess;
    }

    /**
     * 下载
     * @param ftpClient
     * @param filename
     * @param dirPath
     * @param out
     * @return
     */
    public static void download (FTPClient ftpClient, String filename, String dirPath, FileOutputStream out) {
        // 登录
        if (ftpClient != null) {
            try {
                String path = changeEncoding(ftpClient,dirPath);
                changeAndMakeWorkingDir(ftpClient,path);
                String[] fileNames = ftpClient.listNames();
                if (fileNames == null || fileNames.length == 0) {
                    return;
                }
                for (String fileName : fileNames) {
                    String ftpName = new String(fileName.getBytes(SERVER_CHARSET), LOCAL_CHARSET);
                    if (StringUtils.equals(ftpName,filename)) {
                        InputStream in = ftpClient.retrieveFileStream(fileName);
                        IOUtils.copy(in,out);
                    }
                }
            } catch (IOException e) {
                log.error("",e);
            } finally {
                if (out != null){
                    try{
                        out.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        FTPClient ftpClient = login("39.105.71.11",21,"zhhs_admin","eM1gDt#q2Zy4W69R");
        FileInputStream inputStream = new FileInputStream("E:\\test.txt");
        FtpUtil.upload(ftpClient,"中海测试001.txt","/data",inputStream);
        closeConnect(ftpClient);
    }
}

3、sftp

package com.zhhs.common.utils.ftp;

import com.jcraft.jsch.*;
import org.apache.commons.net.ftp.FTPClient;

import java.io.*;
import java.util.Properties;

/**
 * @author peng
 * @version 1.0
 * @date 2023-07-27 10:55
 */
public class SftpUtil {
    /**
     * 获取一个sftp链接
     * @param host sftp服务器ip
     * @param port 端口
     * @param username 用户名
     * @param password 密码
     * @return 返回ChannelSftp
     * @throws Exception 获取通道时的异常
     */
    public static ChannelSftp getSftpChannel(String host, Integer port, String username, String password) throws Exception{
        Session session;
        Channel channel = null;
        JSch jSch = new JSch();
        try {
            session = jSch.getSession(username, host, port);
            session.setPassword(password);

            // 配置链接的属性
            Properties properties = new Properties();
            properties.setProperty("StrictHostKeyChecking","no");
            session.setConfig(properties);

            // 进行sftp链接
            session.connect();

            // 获取通信通道
            channel = session.openChannel("sftp");
            channel.connect();
        } catch (JSchException e) {
            e.printStackTrace();
            throw e;
        }
        return (ChannelSftp)channel;
    }

    /**
     * 上传文件
     * @param channelSftp sftp通道
     * @param localFile 本地文件
     * @param remoteFile 远程文件
     */
    public static void upload(ChannelSftp channelSftp, String localFile, String remoteFile){
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(localFile);
            channelSftp.put(inputStream, remoteFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (SftpException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null){
                try{
                    inputStream.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 从sftp服务器上下载文件
     * @param channelSftp sftp通道
     * @param remoteFile 远程文件
     * @param localFile 本地文件
     */
    public static void download(ChannelSftp channelSftp, String remoteFile, String localFile){
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(localFile);
            channelSftp.get(remoteFile, outputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (SftpException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null){
                try{
                    outputStream.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除文件
     * @param channelSftp sftp通道
     * @param remoteFile 远程文件
     */
    public static void deleteFile(ChannelSftp channelSftp, String remoteFile) throws Exception{
        try {
            channelSftp.rm(remoteFile);
        } catch (SftpException e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 关闭sftp链接
     * @param channelSftp sftp通道
     * @throws Exception 关闭session的异常
     */
    public static void closeSession(ChannelSftp channelSftp) throws Exception{
        if(channelSftp == null){
            return;
        }

        Session session = null;
        try {
            session = channelSftp.getSession();
        } catch (JSchException e) {
            e.printStackTrace();
            throw e;
        }finally {
            if(session != null){
                session.disconnect();
            }
        }

    }

    public static void main(String[] args) throws Exception {
        ChannelSftp sftpClient =  getSftpChannel("39.105.71.11",23091,"zhhs_admin","eM1gDt#q2Zy4W69R");
        //上传
        //SftpUtil.upload(ftpClient,"E:\\test.txt","/data/中海测试.txt");
        //下载
        SftpUtil.download(sftpClient,"/data/中海测试.txt","E:\\大山测试111.txt");
        closeSession(sftpClient);
    }
}