当前位置: 首页 > news >正文

java FTP客户端获取文件流假死问题

依赖 hutool

FTP配置

inspection.data.ftp.host=172.26.1.41
inspection.data.ftp.port=21
inspection.data.ftp.user=6c
inspection.data.ftp.password=6cqq123
inspection.data.ftp.charsetName=GBK

FTP配置类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@Data
@ConfigurationProperties(prefix = "inspection.data.ftp")
public class FtpParamProperties {// ftp ipprivate String host;// ftp 端口private int port;// ftp 用户private String user;// ftp 密码private String password;// ftp 编码private String charsetName;
}

FTP工具类


import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.http.ContentType;
import com.cdtye.itps.cms.config.FtpParamProperties;
import com.cdtye.itps.cms.model.dto.DownloadDto;
import com.cdtye.itps.cms.model.dto.FtpPathTree;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Objects;@Component
public class FtpUtil {static FtpParamProperties ftpParamProperties;public static Ftp getConnect() {return new Ftp(ftpParamProperties.getHost(), ftpParamProperties.getPort(), ftpParamProperties.getUser(), ftpParamProperties.getPassword(), Charset.forName(ftpParamProperties.getCharsetName()));}public static void downLoad(DownloadDto downloadDto, HttpServletResponse response) {if (Objects.isNull(downloadDto)) {throw new RuntimeException("下载参数不能为空");}if (StringUtils.isBlank(downloadDto.getFileName())) {throw new RuntimeException("下载参数中文件名不能为空");}if (StringUtils.isBlank(downloadDto.getUrl())) {throw new RuntimeException("下载参数中url不能为空");}response.reset();response.setContentType(ContentType.OCTET_STREAM.getValue());response.setCharacterEncoding("utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + downloadDto.getFileName());if (StringUtils.isNotBlank(downloadDto.getUrl())) {downFormUrl(downloadDto, response);}}private static void downFormUrl(DownloadDto downloadDto, HttpServletResponse response) {try (InputStream stream = URLUtil.getStream(URLUtil.toUrlForHttp(URLUtil.encodeFragment(downloadDto.getUrl())))) {byte[] buff = new byte[1024];OutputStream os = response.getOutputStream();int i = 0;while ((i = stream.read(buff)) != -1) {os.write(buff, 0, i);os.flush();}} catch (IOException e) {throw new RuntimeException("下载文件异常", e);}}public static FtpPathTree recursionLs(String rootPath, Filter<FTPFile> filter) throws Exception {if (StringUtils.isBlank(rootPath)) {throw new RuntimeException("目录路径不能为空");}FtpPathTree ftpPathTree = new FtpPathTree();try (Ftp ftp = FtpUtil.getConnect()) {if (!ftp.exist(rootPath)) {throw new RuntimeException("目录不存在");}ftpPathTree.setFileName(rootPath);ftpPathTree.setFileFullPath(rootPath);List<FTPFile> ftpFiles = ftp.lsFiles(rootPath, filter);if (CollectionUtils.isNotEmpty(ftpFiles)) {recursionChild(ftpFiles, ftp, ftpPathTree, filter);}} catch (Exception e) {throw e;}return ftpPathTree;}private static FtpPathTree recursionChild(List<FTPFile> ftpFiles, Ftp ftp, FtpPathTree ftpPathTree, Filter<FTPFile> filter) {if (CollectionUtils.isNotEmpty(ftpFiles)) {for (FTPFile ftpFile : ftpFiles) {String currentPath = ftpPathTree.getFileFullPath() + "/" + ftpFile.getName();if (ftpFile.isDirectory()) {
//                    Filter<FTPFile> filterDirectory = (f) -> Objects.nonNull(f);List<FTPFile> ftpFiles1 = ftp.lsFiles(currentPath, filter);if (CollectionUtils.isNotEmpty(ftpFiles1)) {FtpPathTree ftpPathTree2 = new FtpPathTree();ftpPathTree2.setFileName(ftpFile.getName());ftpPathTree2.setFileFullPath(currentPath);ftpPathTree.getChilds().add(recursionChild(ftpFiles1, ftp, ftpPathTree2, filter));} else {FtpPathTree ftpPathTree1 = new FtpPathTree();ftpPathTree1.setFileName(ftpFile.getName());ftpPathTree1.setFileFullPath(currentPath);ftpPathTree.getChilds().add(ftpPathTree1);}} else {FtpPathTree ftpPathTree1 = new FtpPathTree();ftpPathTree1.setFileName(ftpFile.getName());ftpPathTree1.setFileFullPath(currentPath);ftpPathTree1.setFileFlag(Boolean.TRUE);ftpPathTree.getChilds().add(ftpPathTree1);}}}return ftpPathTree;}public static void recursionFile(List<FtpPathTree> ftpPathTrees, FtpPathTree ftpPathTree) {if (Objects.nonNull(ftpPathTree)) {if (ftpPathTree.getFileFlag()) {ftpPathTrees.add(ftpPathTree);} else {if (CollectionUtils.isNotEmpty(ftpPathTree.getChilds())) {for (FtpPathTree child : ftpPathTree.getChilds()) {recursionFile(ftpPathTrees, child);}}}}}public static void downloadFile(String fileFullPath, HttpServletResponse response) throws Exception {if (StringUtils.isBlank(fileFullPath)) {throw new RuntimeException("文件路径不能为空!");}try (ServletOutputStream outputStream = response.getOutputStream(); Ftp ftp = FtpUtil.getConnect()) {if (!ftp.exist(fileFullPath)) {throw new RuntimeException("文件不存在!");}if (ftp.isDir(fileFullPath)) {throw new RuntimeException("只能下载文件!");}response.reset();String fullFileName = FileNameUtil.getName(fileFullPath);String filePath = StringUtils.substringBefore(fileFullPath, fullFileName);response.setCharacterEncoding("UTF-8");response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'"+ URLEncoder.encode(fullFileName, "UTF-8").replace("+", "%20"));ftp.download(filePath, fullFileName, outputStream);outputStream.flush();}}@Autowiredpublic void setFtpParamProperties(FtpParamProperties ftpParamProperties) {FtpUtil.ftpParamProperties = ftpParamProperties;}
}

测试类

import cn.hutool.extra.ftp.Ftp;
import com.cdtye.itps.cms.util.FtpUtil;
import org.apache.commons.net.ftp.FTPClient;import java.io.InputStream;
import java.util.Objects;public class FTPTest {public static void main(String[] args) {try (Ftp ftp = FtpUtil.getConnect()) {FTPClient client = ftp.getClient();InputStream inputStream = null;try {// 开始主动模式client.enterLocalPassiveMode();inputStream = client.retrieveFileStream("FTP路径");if (Objects.nonNull(inputStream)) {// 拿到流做事情}} catch (Exception e) {} finally {if (Objects.nonNull(inputStream)) {inputStream.close();}//重点是这两行,解决假死问题client.sendNoOp();client.completePendingCommand();}} catch (Exception e) {}}
}

相关文章:

java FTP客户端获取文件流假死问题

依赖 hutool FTP配置 inspection.data.ftp.host172.26.1.41 inspection.data.ftp.port21 inspection.data.ftp.user6c inspection.data.ftp.password6cqq123 inspection.data.ftp.charsetNameGBK FTP配置类 import lombok.Data; import org.springframework.boot.context.pr…...

python使用记录

1、VSCode添加多个python解释器 只需要将对应的python.exe的目录&#xff0c;添加到系统环境变量的Path中即可&#xff0c;VSCode会自动识别及添加 2、pip 使用 pip常用命令和一些坑 查看已安装库的版本号 pip show 库名称 通过git 仓库安装第三方库 pip install git仓库地…...

【Vulnhub 靶场】【Coffee Addicts: 1】【简单-中等】【20210520】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/coffee-addicts-1,699/ 靶场下载&#xff1a;https://download.vulnhub.com/coffeeaddicts/coffeeaddicts.ova 靶场难度&#xff1a;简单 - 中等 发布日期&#xff1a;2021年5月20日 文件大小&#xff1a;1.3 …...

codeforces每日两道思维题(第 二 天)

第二天 1 B. Same Parity Summands 原题链接&#xff1a;Problem - 1352B - Codeforces rating : 1200 题目描述&#xff1a; 给定两个正整数 n&#xff08;1≤n≤10^9&#xff09;和 k&#xff08;1≤k≤100&#xff09;。将数字 n 表示为 k 个相同奇偶性的正整数之和&…...

【网络安全】-常见的网站攻击方式详解

文章目录 介绍1. SQL 注入攻击攻击原理攻击目的防范措施 2. 跨站脚本攻击&#xff08;XSS&#xff09;攻击原理攻击目的防范措施 3. CSRF 攻击攻击原理攻击目的防范措施 4. 文件上传漏洞攻击原理攻击目的防范措施 5. 点击劫持攻击原理攻击目的防范措施 结论 介绍 在数字时代&a…...

ElasticSearch学习笔记(一)

计算机软件的学习&#xff0c;最重要的是举一反三&#xff0c;只要大胆尝试&#xff0c;认真验证自己的想法就能收到事办功倍的效果。在开始之前可以看看别人的教程做个快速的入门&#xff0c;然后去官方网站看看官方的教程&#xff0c;有中文教程固然是好&#xff0c;没有中文…...

go写文件后出现大量NUL字符问题记录

目录 背景 看看修改前 修改后 原因 背景 写文件完成后发现&#xff1a; size明显也和正常的不相等。 看看修改前 buf : make([]byte, 64) buffer : bytes.NewBuffer(buf)// ...其它逻辑使得buffer有值// 打开即将要写入的文件&#xff0c;不存在则创建 f, err : os.Open…...

【Collection - PriorityQueue源码解析】

本文主要对Collection - PriorityQueue进行源码解析。 Collection - PriorityQueue源码解析 概述方法剖析 add()和offer()element()和peek()remove()和poll()remove(Object o) 概述 前面以Java ArrayDeque为例讲解了Stack和Queue&#xff0c;其实还有一种特殊的队列叫做Priori…...

Javascript_根据截止日期超时自动返回

例如定时交卷功能&#xff0c;隐藏一个input id"endTime"存放超时时间&#xff0c;例如2023-12-01 20:56:15&#xff0c;使用如下代码即可实现超时自动处理。 <script src"/jquery.min.js"></script><script type"text/javascript&qu…...

记录 | vscode设置自动换行

右上菜单栏 -> 查看 -> 打开自动换行 或者还有种方式&#xff0c;如下&#xff0c; 左下角小齿轮&#xff0c;点击设置 然后输入 Editor: Word Wrap &#xff0c;把开关打开为 on...

k8s引用环境变量

一 定义环境变量 ① 如何在k8s中定义环境变量 env、configmap、secret补充&#xff1a; k8s 创建Service自带的环境变量 ② 从pod属性中获取 kubectl explain deploy.spec.template.spec.containers.env.valueFrom关注&#xff1a; configMapKeyRef、fieldRef 和 resour…...

navicate16 2059 plugin http could not be loaded

plugin http could not be loaded 乱码 library path http.dll 今天新装一台机子的navicate遇到这个问题。 查了半天都是说 caching_sha2_password’的解决办法。 然后是咋解决的呢&#xff0c;真是丢脸 由于我是直接从浏览器复制下来的ip&#xff0c;所以虽然我只复制了ip地…...

dp-基础版动态规划(动态规划每日一题计划)10/50

最小路径和 class Solution {public static int minPathSum(int[][] grid) {int dp[][]new int[grid.length][grid[0].length];dp[0][0]grid[0][0];for(int i1;i<grid[0].length;i){dp[0][i]grid[0][i]dp[0][i-1];}for(int i1;i<grid.length;i){dp[i][0]grid[i][0]dp[i-…...

轻食沙拉店外卖配送小程序商城效果如何

轻食沙拉店也是餐饮业中较为受欢迎的品类&#xff0c;其具备健康属性绿色食材涵盖广泛人群&#xff0c;虽然如此&#xff0c;但也缺乏一定市场教育&#xff0c;部分消费者依然对这一类目知之甚少&#xff0c;而商家想要进一步扩大生意&#xff0c;就需要不断品牌宣传、餐品销售…...

Oracle ADRCI工具使用说明

1.ADRCI介绍 ADRCI是一个命令行工具&#xff0c;是Oracle 11g中引入的故障可诊断性架构的一部分。 ADRCI可以完成以下&#xff1a; 查看自动诊断信息库&#xff08;ADR&#xff09;中的诊断数据。 查看Health Monitor报告。 将事件和问题信息打包到zip文件中以传输到Oracle Su…...

Amazon CodeWhisperer 正式可用, 并面向个人开发者免费开放

文章作者&#xff1a;深度-围观 北京——2023年4月18日&#xff0c;亚马逊云科技宣布&#xff0c;实时 AI 编程助手 Amazon CodeWhisperer 正式可用&#xff0c;同时推出的还有供所有开发人员免费使用的个人版&#xff08;CodeWhisperer Individual&#xff09;。CodeWhisperer…...

8-Hive原理与技术

单选题 题目1&#xff1a;按粒度大小的顺序&#xff0c;Hive数据被分为&#xff1a;数据库、数据表、桶和什么 选项: A 元祖 B 栏 C 分区 D 行 答案&#xff1a;C ------------------------------ 题目2&#xff1a;以下选项中&#xff0c;哪种类型间的转换是被Hive查询语言…...

cloudflare Tunnel完整

下载和安装 curl -L ‘https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64’ -o ./cloudflared-linux-amd64 280 chmod x ./cloudflared-linux-amd64 281 ./cloudflared-linux-amd64 282 mv cloudflared-linux-amd64 cloudflared …...

微信聊天窗口测试用例

以前没测过客户端的测试&#xff0c;昨天面试被问到聊天窗口测试场景设计&#xff0c;感觉自己答的不好&#xff0c;结束后上网查了一下客户端/app测试的要点&#xff0c;按照测试策略来分&#xff0c;主要涉及到如下测试类型&#xff1a; 1、功能测试 2、性能测试 3、界面测试…...

Linux下配置邮箱客户端MUTT,整合msmtp + procmail + fetchmail

一、背景 在向 Linux kernel 社区提交patch补丁步骤总结&#xff08;已验证成功&#xff09;_kernel补丁-CSDN博客文章中提到如何向kernel社区以及其他类似如qemu、libvirt社区提交patch的详细步骤&#xff0c;但还有一点不足的是通过git send-email这种方法基本是只能发送patc…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...