1、ftp

java实现ftp上传下载,可以借助apache的commons-net包来完成。

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.util.List;
import java.util.Map;

public class FtpUtils {
    private static FTPClient ftpClient;

    /**
     * 获取ftpClient
     * @param host 主机ip
     * @param port 端口号
     * @param username ftp用户名
     * @param password ftp密码
     * @return FTPClient对象
     */
    private static FTPClient getFTPClient(String host,int port,String username,String password) {
        ftpClient = new FTPClient();
        try {
            //连接ftp服务器
            ftpClient.connect(host, port);
            //登录ftp
            ftpClient.login(username, password);
        } catch (IOException e) {
            LogUtil.error("连接ftp服务器异常!",e);
            return ftpClient;
        }

        //设置编码方式
        ftpClient.setControlEncoding("UTF-8");
        try {
            //设置文件类型,二进制文件
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        } catch (IOException e) {
            LogUtil.error("设置文件类型异常!",e);
            return ftpClient;
        }
        //设置被动模式(默认方式)
        ftpClient.enterLocalPassiveMode();
        if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
            //连接失败
            try {
                ftpClient.disconnect();
            } catch (IOException e) {
                LogUtil.error("关闭ftpClient异常!",e);
            }
        } else {
            LogUtil.info("ftp连接成功!");
        }
        return ftpClient;
    }

    private static void free(){
        try {
            ftpClient.logout();
            ftpClient.disconnect();
            LogUtil.info("ftp断开连接!");
        } catch (IOException e) {
            LogUtil.error("ftpClient连接关闭异常",e);
        }
    }

    /**
     * ftp多文件上传
     * @param host 主机ip
     * @param port 主机端口号
     * @param username ftp用户名
     * @param password ftp密码
     * @param remotePath 远程目录
     * @param localPathList 本地文件路径集合,每个元素为带文件名的全路径
     * @return 上传成功的文件个数
     */
    public static int uploadMultipleFile(String host, int port, String username, String password, String remotePath, List<String> localPathList){
        final int ZERO = 0;
        int successNum = 0;

        //连接ftp客户端
        FTPClient ftpClient = getFTPClient(host, port, username, password);
        //切换工作路径
        try {
            ftpClient.changeWorkingDirectory(remotePath);
        } catch (IOException e) {
            LogUtil.error("远程路径错误:"+remotePath,e);
            return ZERO;
        }
        int reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            LogUtil.info("ftpClient未准备就绪,即将断开连接!");
            free();
            return ZERO;
        }else{
            //准备就绪,开始上传文件
            ftpClient.enterLocalActiveMode();
            String fileName = null;
            for (String localPath : localPathList) {
                try(InputStream in = new FileInputStream(localPath);) {
                    //去除路径,获取文件名
                    fileName = localPath.substring(localPath.lastIndexOf("/")+1, localPath.length());
                    //上传时文件名支持中文
                    fileName = new String(fileName.getBytes("GBK"), FTP.DEFAULT_CONTROL_ENCODING);
                    //上传文件
                    if (ftpClient.storeFile(fileName, in)) {
                        LogUtil.info("文件上传成功:"+localPath);
                        successNum++;
                    }else{
                        LogUtil.info("文件上传失败:"+localPath);
                    }
                } catch (IOException e) {
                    LogUtil.error("文件上传失败:"+localPath,e);
                }
            }
            free();
        }


        return successNum;
    }


    /**
     * 多文件下载
     * @param host 主机ip
     * @param port 端口号
     * @param username sftp用户名
     * @param password sftp密码
     * @param srcToDstMap 每个元素的key为带文件名的远程全路径,value为带文件名的本地全路径
     * @return 下载成功的个数
     */
    public static int downloadMultipleFile(String host, int port, String username, String password, Map<String,String> srcToDstMap){
        int successNum = 0;
        final int ZERO = 0;
        //连接ftp客户端
        FTPClient ftpClient = getFTPClient(host, port, username, password);

        int reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            LogUtil.info("ftpClient未准备就绪,即将断开连接!");
            free();
            return ZERO;
        }else{
            for (Map.Entry<String, String> entry : srcToDstMap.entrySet()) {
                String src = entry.getKey();
                String srcForLog = src;
                try(OutputStream out = new FileOutputStream(entry.getValue())){
                    src = new String(src.getBytes("GBK"), FTP.DEFAULT_CONTROL_ENCODING);
                    if(ftpClient.retrieveFile(src, out)){
                        successNum++;
                        LogUtil.info("ftp下载成功:"+srcForLog);
                    }else{
                        LogUtil.info("ftp下载失败:"+srcForLog);
                    }
                } catch (Exception e) {
                    LogUtil.error("ftp下载失败:"+srcForLog, e);
                }

            }
            free();
            return successNum;
        }

    }

}

 

2、sftp

sftp是ssh ftp,java要想实现sftp上传下载,需借助第三方工具包jsch来完成。

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;

public class SftpUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(SftpUtil.class);
    
    public static ChannelSftp getconnect(String host,int port,String username, String password) {
        ChannelSftp sftp = null;
        try {
            JSch jsch = new JSch();
            Session sshSession = jsch.getSession(username, host, port);
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            LOGGER.info("sftp登录成功!");
        } catch (Exception e) {
            LOGGER.error("sftp登录失败!"+e.getMessage(),e);
        }
        return sftp;
    }

    public static void disconnect(ChannelSftp sftp) {
        try {
            if (sftp != null) {
                Session session = sftp.getSession();
                if(session.isConnected()){
                    session.disconnect();
                }
            }
        } catch (JSchException e) {
            LOGGER.error("关闭sftp会话异常:"+e.getMessage(),e);
        }
    }

    public static int upload(ChannelSftp sftp,String host,int port,String username,String password,List<LocalRemoteInfo> localRemoteInfos){
        int sucNum = 0;
        if(null == sftp || !sftp.isConnected()){
            LOGGER.info("sftp未连接!");
            return sucNum;
        }
        try {
            for (LocalRemoteInfo localRemoteInfo : localRemoteInfos) {
                sftp.cd(localRemoteInfo.getRemotePath());
                sftp.put(localRemoteInfo.getLocalPath(), Paths.get(localRemoteInfo.getLocalPath()).toFile().getName());
                sucNum++;
            }
        }catch (SftpException e){
            LOGGER.error("文件上传异常:"+e.getMessage(),e);
        }
        return sucNum;
    }

    public static int download(ChannelSftp sftp,String host,int port,String username,String password,List<LocalRemoteInfo> localRemoteInfos){
        int sucNum = 0;
        if(null == sftp || !sftp.isConnected()){
            LOGGER.info("sftp未连接!");
            return sucNum;
        }
        try {
            for (LocalRemoteInfo localRemoteInfo : localRemoteInfos) {
                sftp.get(localRemoteInfo.getRemotePath(), localRemoteInfo.getLocalPath());
                sucNum++;
            }
        } catch (SftpException e) {
            LOGGER.error("文件下载异常:"+e.getMessage(),e);
        }
        return sucNum;
    }

    public static class LocalRemoteInfo{
        private String localPath;
        private String remotePath;

        public String getLocalPath() {
            return localPath;
        }

        public void setLocalPath(String localPath) {
            this.localPath = localPath;
        }

        public String getRemotePath() {
            return remotePath;
        }

        public void setRemotePath(String remotePath) {
            this.remotePath = remotePath;
        }
    }

}