SpringBoot实现从SFTP读取文件并打包ZIP下载

最近做到一个需求,是需要根据日期及文件名称(非必填)从SFTP服务器上读取文件并压缩成ZIP文件给用户下载,简单记录一下实现的思路

1.首先使用账号密码连接到SFTP中

/**
     * 登录SFTP
     *
     * @param  userName  用户名
     * @param  password  密码
     * @param  host      主机地址
     */
    private ChannelSftp loginSftp(String userName, String password, String host, int port) {
        JSch jsch = new JSch();
        try {
            Session sshSession = jsch.getSession(userName, host, port);
            sshSession.setPassword(password);
            sshSession.setConfig("StrictHostKeyChecking", "no");
            sshSession.connect(sftpDownConfig.getSessionConnectTimeout());
            Channel channel = sshSession.openChannel("sftp");
            channel.connect(sftpDownConfig.getChannelConnectTimeout());
            return (ChannelSftp) channel;
        } catch (JSchException e) {
            log.error("loginSftp error,errorMessage", e);
        }
        return null;
    }

2.根据地址访问目录并打包返回ZIP文件流,由于需求文件名称是非必填,所以需要根据类型判断是日期的话打包目录下所有文件,如果为名称则打包对应名称。

private ZipArchiveOutputStream zipFile(String dir, List<String> files, ChannelSftp channelSftp, ZipArchiveOutputStream zipOut){
        for (String fileName : files) {
            String filePath = dir + "/" + fileName;
            boolean exist = checkFileExist(filePath, channelSftp);
            if (!exist) {
                log.error("文件 {} 不存在", filePath);
                return null;
            }
            try (InputStream inputStream = channelSftp.get(filePath)) {
                if (inputStream != null) {
                    ZipArchiveEntry entry = new ZipArchiveEntry(fileName);
                    zipOut.putArchiveEntry(entry);

                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        zipOut.write(buffer, 0, bytesRead);
                    }
                    zipOut.closeArchiveEntry();
                } else {
                    log.error("文件 {} 未找到", filePath);
                }
            } catch (SftpException | IOException e) {
                log.error("处理文件 {} 时出错", filePath, e);
            }
        }
        return zipOut;
    }
private boolean returnZip(HttpServletResponse response, String dir, String date, List<String> files, ChannelSftp channelSftp){
        try {
            // 设置响应头
            response.setContentType("application/zip");
            String zipFileName = date + "_sftp_files.zip";
            response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);

            ServletOutputStream outputStream = response.getOutputStream();
            ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(outputStream);
            ZipArchiveOutputStream zipArchiveOutputStream = zipFile(dir, files, channelSftp, zipOut);
            if (zipArchiveOutputStream == null) {
                log.error("文件不存在,压缩失败");
                return false;
            }

            zipOut.finish();
            zipOut.close();
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            log.error("写入响应流时出错", e);
        } finally {
            logoutSftp(channelSftp);
        }
        return true;
    }

3.断开SFTP连接

/**
     * 关闭SFTP
     */
    private void logoutSftp(ChannelSftp channelSftp) {
        try {
            if (channelSftp == null) {
                return;
            }
            if (channelSftp.isConnected()) {
                channelSftp.disconnect();
            }
            if (channelSftp.getSession() != null) {
                channelSftp.getSession().disconnect();
            }
        } catch (Exception ex) {
            log.error("logoutSftp error,errorMessage", ex);
        }
    }

最后在main方法做好参数的设置及逻辑的判断,调用这些方法就行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值