Java使用sftp文件服务器

1.简介

在工作中,对接第三方服务时,往往存在文件的传输使用,使用stfp是一种简单有效的方式,可以对文件进行上传和下载。下面是使用sftp文件服务器的demo,可以作为工具类放入项目中,即可简单上手和使用。

FtpClient.java

public class FtpUtil {
    
    
    private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);

    public FtpUtil() {
    
    
    }
    
public static enum ProxyType {
    
    
        HTTP;

        private ProxyType() {
    
    
        }
    }

    public static class FtpDto implements Serializable {
    
    
        private static final long serialVersionUID = 2610830652396624141L;
        private String ip;
        private int port;
        private String user;
        private String password;
        private String remoteDir;
        private String localFilePathName;
        private String remoteFileName;
        private FtpUtil.ProxyType proxyType;
        private String proxyHost;
        private int proxyPort;

        public FtpDto() {
    
    
        }

        public String getIp() {
    
    
            return this.ip;
        }

        public void setIp(String ip) {
    
    
            this.ip = ip;
        }

        public int getPort() {
    
    
            return this.port;
        }

        public void setPort(int port) {
    
    
            this.port = port;
        }

        public String getUser() {
    
    
            return this.user;
        }

        public void setUser(String user) {
    
    
            this.user = user;
        }

        public String getPassword() {
    
    
            return this.password;
        }

        public void setPassword(String password) {
    
    
            this.password = password;
        }

        public String getRemoteDir() {
    
    
            return this.remoteDir;
        }

        public void setRemoteDir(String remoteDir) {
    
    
            this.remoteDir = remoteDir;
        }

        public String getLocalFilePathName() {
    
    
            return this.localFilePathName;
        }

        public void setLocalFilePathName(String localFilePathName) {
    
    
            this.localFilePathName = localFilePathName;
        }

        public String getRemoteFileName() {
    
    
            return this.remoteFileName;
        }

        public void setRemoteFileName(String remoteFileName) {
    
    
            this.remoteFileName = remoteFileName;
        }

        public FtpUtil.ProxyType getProxyType() {
    
    
            return this.proxyType;
        }

        public void setProxyType(FtpUtil.ProxyType proxyType) {
    
    
            this.proxyType = proxyType;
        }

        public String getProxyHost() {
    
    
            return this.proxyHost;
        }

        public void setProxyHost(String proxyHost) {
    
    
            this.proxyHost = proxyHost;
        }

        public int getProxyPort() {
    
    
            return this.proxyPort;
        }

        public void setProxyPort(int proxyPort) {
    
    
            this.proxyPort = proxyPort;
        }
    }
}

SftpClient.java

public class SftpClient {
    
    

    /**
     * 上传文件
     * 
     * @param ip
     * @param port
     * @param user
     * @param password
     * @param localFilePath
     * @param remoteDir
     * @param remoteFileName
     * @param useProxy
     */
    public static final String PROXY_HOST = "XXXX";
    public static final int PROXY_PORT = XX;

    public static void upload(String ip, int port, String user, String password, String localFilePath, String remoteDir,
                              String remoteFileName, boolean useProxy) {
    
    
        FtpDto ftpDto = new FtpDto();
        ftpDto.setIp(ip);
        ftpDto.setPort(port);
        ftpDto.setUser(user);
        ftpDto.setPassword(password);
        if (useProxy) {
    
    
            ftpDto.setProxyType(ProxyType.HTTP);
            ftpDto.setProxyHost(PROXY_HOST);
            ftpDto.setProxyPort(PROXY_PORT);
        }

        ftpDto.setRemoteDir(remoteDir);
        ftpDto.setLocalFilePathName(localFilePath);
        ftpDto.setRemoteFileName(remoteFileName);

        SftpUtil.upload(ftpDto);
    }

    /**
     * 下载文件
     * 
     * @param ip
     * @param port
     * @param user
     * @param password
     * @param localFilePath
     * @param remoteDir
     * @param remoteFileName
     * @param useProxy
     */
    public static void download(String ip, int port, String user, String password, String localFilePath,
                                String remoteDir, String remoteFileName, boolean useProxy) {
    
    
        FtpDto ftpDto = new FtpDto();
        ftpDto.setIp(ip);
        ftpDto.setPort(port);
        ftpDto.setUser(user);
        ftpDto.setPassword(password);
        if (useProxy) {
    
    
            ftpDto.setProxyType(ProxyType.HTTP);
            ftpDto.setProxyHost(PROXY_HOST);
            ftpDto.setProxyPort(PROXY_PORT);
        }

        ftpDto.setRemoteDir(remoteDir);
        ftpDto.setLocalFilePathName(localFilePath);
        ftpDto.setRemoteFileName(remoteFileName);

        SftpUtil.download(ftpDto);
    }
}

SftpUtil.java

pom依赖

        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
        </dependency>
import com.jcraft.jsch.*;

public class SftpUtil {
    
    

    private static int timeout = 60000;

    private static final Logger logger  = LoggerFactory.getLogger(SftpUtil.class);

    private static ChannelItem getChannel(FtpDto ftpDto) throws Exception {
    
    
        JSch jsch = new JSch();
        Session session = jsch.getSession(ftpDto.getUser(), ftpDto.getIp(), ftpDto.getPort());
        session.setPassword(ftpDto.getPassword());
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.setTimeout(timeout);
        if (!StringUtils.isBlank(ftpDto.getProxyHost())) {
    
    
            ProxyHTTP proxy = new ProxyHTTP(ftpDto.getProxyHost(), ftpDto.getProxyPort());
            session.setProxy(proxy);
        }
        session.connect();
        Channel channel = session.openChannel("sftp");
        channel.connect();

        ChannelItem channelItem = new ChannelItem();
        channelItem.setChannel((ChannelSftp) channel);
        channelItem.setSession(session);
        return channelItem;
    }

    private static void closeChannel(ChannelItem channelItem) {
    
    
        try {
    
    
            if (channelItem.getSession() != null) {
    
    
                channelItem.getSession().disconnect();
            }
        } catch (Exception e1) {
    
    
            logger.warn("退出SFTP管道异常");
        }
        try {
    
    
            if (channelItem.getChannel() != null) {
    
    
                channelItem.getChannel().disconnect();
            }
        } catch (Exception e1) {
    
    
            logger.warn("退出SFTP管道异常");
        }
    }

    public static void upload(FtpDto ftpDto) {
    
    
        upload(ftpDto, null);
    }

    public static void upload(FtpDto ftpDto, String capSubCodePath) {
    
    
        logger.info("开始SFTP文件上传:{}", ftpDto.toString());
        ChannelSftp chSftp = null;
        ChannelItem channelItem = null;
        InputStream is = null;
        try {
    
    
            channelItem = SftpUtil.getChannel(ftpDto);
            chSftp = (ChannelSftp) channelItem.getChannel();
            try {
    
    
                if (StringUtils.isNotEmpty(capSubCodePath)) {
    
    
                    if (!isDirExist(chSftp, capSubCodePath)) {
    
    
                        chSftp.mkdir(capSubCodePath);
                    }
                }
                if (!isDirExist(chSftp, ftpDto.getRemoteDir())) {
    
    
                    createDir(chSftp, ftpDto.getRemoteDir());
                }
                logger.info("创建目录成功:{}", ftpDto.getRemoteDir());
            } catch (SftpException e) {
    
    
                logger.error("创建目录失败:{}", ftpDto.getRemoteDir(), e);
            }

            String upPath = ftpDto.getRemoteDir();
            if (!(upPath.endsWith(File.separator) || upPath.endsWith("/"))) {
    
    
                upPath = upPath.concat(File.separator);
            }
            upPath = upPath.concat(ftpDto.getRemoteFileName());
            OutputStream out = chSftp.put(upPath, ChannelSftp.OVERWRITE);
            byte[] buff = new byte[1024 * 256];
            int read;
            if (out != null) {
    
    
                is = new FileInputStream(ftpDto.getLocalFilePathName());
                do {
    
    
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
    
    
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
            }
        } catch (Exception e) {
    
    
            logger.error("SFTP文件上传失败", e);
            throw new ServiceException(CommonErrorCode.ERROR_FILE_UPLOAD, e, new String[] {
    
     ftpDto.getRemoteFileName() + "文件上传失败" }, e.getMessage());
        } finally {
    
    
            if (chSftp != null) {
    
    
                try {
    
    
                    chSftp.quit();
                } catch (Exception e) {
    
    
                    logger.warn("退出SFTP管道异常");
                }
            }
            if (is != null) {
    
    
                try {
    
    
                    is.close();
                } catch (Exception e) {
    
    
                    logger.warn("关闭InputStream异常");
                }
            }
            closeChannel(channelItem);
        }
        logger.info("成功SFTP文件上传:{}", ftpDto.getLocalFilePathName());
    }

    /**
     * 批量文件上传
     * 
     * @param ftpDto
     * @return
     * @throws Exception
     */
    public static boolean batchUploadFile(List<FtpDto> ftpDtoList) throws Exception {
    
    
        ChannelItem channelItem = SftpUtil.getChannel(ftpDtoList.get(0));
        try {
    
    
            ChannelSftp chSftp = (ChannelSftp) channelItem.getChannel();
            boolean flag = batchUploadFile(chSftp, ftpDtoList);
            return flag;
        } catch (Exception e) {
    
    
            logger.error("SftpUtil.batchUploadFile上传异常:", e);
        } finally {
    
    
            closeChannel(channelItem);
        }
        return false;
    }

    /**
     * 批量文件上传
     * 
     * @param ftpDto
     * @return
     */
    private static boolean batchUploadFile(ChannelSftp chSftp, List<FtpDto> ftpDtoList) {
    
    
        boolean doneFlag = false;
        try {
    
    
            for (FtpDto ftpDto : ftpDtoList) {
    
    
                boolean flag = uploadFile(chSftp, ftpDto);
                if (!flag) {
    
    
                    doneFlag = false;
                    logger.error("SftpUtil.batchUploadFile上传失败:FilePathName:{}", ftpDto.getLocalFilePathName());
                    break;
                } else {
    
    
                    doneFlag = true;
                    logger.info("SftpUtil.batchUploadFile上传成功:FilePathName:{}", ftpDto.getLocalFilePathName());
                }
            }
        } catch (Exception e) {
    
    
            doneFlag = false;
            logger.error("SftpUtil.batchUploadFile上传异常:", e);
        }
        return doneFlag;

    }

    private static boolean uploadFile(ChannelSftp chSftp, FtpDto ftpDto) {
    
    
        InputStream is = null;
        try {
    
    
            if (!isDirExist(chSftp, ftpDto.getRemoteDir())) {
    
    
                createDir(chSftp, ftpDto.getRemoteDir());
            }
            OutputStream out = chSftp.put(ftpDto.getRemoteDir().concat(ftpDto.getRemoteFileName()), ChannelSftp.OVERWRITE);
            byte[] buff = new byte[1024 * 256];
            int read;
            if (out != null) {
    
    
                is = new FileInputStream(ftpDto.getLocalFilePathName());
                do {
    
    
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
    
    
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
            }
            return true;
        } catch (Exception e) {
    
    
            logger.error("SftpUtil文件上传上传异常:", e);
            throw new ServiceException(CommonErrorCode.ERROR_FILE_UPLOAD, e, new String[] {
    
     ftpDto.getRemoteFileName() + "文件上传失败" }, e.getMessage());
        } finally {
    
    
            if (chSftp != null) {
    
    
                try {
    
    
                    chSftp.quit();
                } catch (Exception e) {
    
    
                    logger.warn("退出SFTP管道异常");
                }
            }
            if (is != null) {
    
    
                try {
    
    
                    is.close();
                } catch (Exception e) {
    
    
                    logger.warn("关闭InputStream异常");
                }
            }
        }
    }

    private static void createDir(ChannelSftp chSftp, String directory) {
    
    
        try {
    
    
            if (directory == null) {
    
    
                return;
            }
            if (isDirExist(chSftp, directory)) {
    
    
                chSftp.cd(directory);
            }
            String pathArry[] = directory.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
    
    
                if (path.equals("")) {
    
    
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(chSftp, filePath.toString())) {
    
    
                    logger.info("进入并设置为当前目录0:{}", filePath.toString());
                    chSftp.cd(filePath.toString());
                } else {
    
    
                    // 建立目录
                    logger.info("建立目录:{}", filePath.toString());
                    chSftp.mkdir(filePath.toString());
                    // 进入并设置为当前目录
                    logger.info("进入并设置为当前目录:{}", filePath.toString());
                    chSftp.cd(filePath.toString());
                }
            }
            chSftp.cd(directory);
        } catch (SftpException e) {
    
    
            logger.error("创建目录失败:{}", directory, e);
        }
    }

    private static boolean isDirExist(ChannelSftp chSftp, String directory) {
    
    
        boolean isDirExistFlag = false;
        try {
    
    
            SftpATTRS sftpATTRS = chSftp.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
    
    
            if (e.getMessage().toLowerCase().equals("no such file")) {
    
    
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }

    public static void download(FtpDto ftpDto) {
    
    
        logger.info("开始SFTP文件下载:{}", ftpDto.toString());
        ChannelSftp chSftp = null;
        ChannelItem channelItem = null;
        OutputStream out = null;
        try {
    
    
            channelItem = SftpUtil.getChannel(ftpDto);
            chSftp = (ChannelSftp) channelItem.getChannel();
            InputStream is = chSftp.get(ftpDto.getRemoteDir().concat(ftpDto.getRemoteFileName()));
            out = new FileOutputStream(ftpDto.getLocalFilePathName());
            byte[] buff = new byte[1024 * 2];
            int read;
            if (is != null) {
    
    
                do {
    
    
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
    
    
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
            }
        } catch (Exception e) {
    
    
            logger.warn("SFTP文件下载失败:" + ftpDto.getRemoteDir().concat(ftpDto.getRemoteFileName()), e);
            throw new ServiceException(CommonErrorCode.ERROR_FILE_UPLOAD, e, new String[] {
    
     "文件下载失败" }, ftpDto.getRemoteFileName());
        } finally {
    
    
            if (chSftp != null) {
    
    
                try {
    
    
                    chSftp.quit();
                } catch (Exception e) {
    
    
                    logger.warn("退出SFTP管道异常");
                }
            }
            if (out != null) {
    
    
                try {
    
    
                    out.close();
                } catch (Exception e) {
    
    
                    logger.warn("关闭OutputStream异常");
                }
            }
            closeChannel(channelItem);
        }
        logger.info("成功SFTP文件下载:{}", ftpDto.getLocalFilePathName());
    }

    static class ChannelItem {
    
    

        Session session;
        Channel channel;

        public Session getSession() {
    
    
            return session;
        }

        public void setSession(Session session) {
    
    
            this.session = session;
        }

        public Channel getChannel() {
    
    
            return channel;
        }

        public void setChannel(Channel channel) {
    
    
            this.channel = channel;
        }
    }

    public static class MyProgressMonitor implements SftpProgressMonitor {
    
    

        private long transfered;

        public MyProgressMonitor(long transfered) {
    
    
            this.transfered = transfered;
        }

        @Override
        public boolean count(long count) {
    
    
            transfered = transfered + count;
            return true;
        }

        @Override
        public void end() {
    
    
        }

        @Override
        public void init(int op, String src, String dest, long max) {
    
    
        }
    }
}
    }

    public static class MyProgressMonitor implements SftpProgressMonitor {
    
    

        private long transfered;

        public MyProgressMonitor(long transfered) {
    
    
            this.transfered = transfered;
        }

        @Override
        public boolean count(long count) {
    
    
            transfered = transfered + count;
            return true;
        }

        @Override
        public void end() {
    
    
        }

        @Override
        public void init(int op, String src, String dest, long max) {
    
    
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38951230/article/details/128481560
今日推荐