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

手把手教学 Springboot+ftp+下载图片

简单教学,复制即用的Ftp下载图片
引入配置包

        <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.9.0</version></dependency>

首先创建连接客户端,中间如果赋值进去找不到变量,则是自己需要配置的 ,比如host:则表示主机ip

public FTPClient connFtp() {FTPClient ftpClient = null;String errorMsg = null;try {ftpClient = new FTPClient();//设置连接超时时间ftpClient.setConnectTimeout(1000 * 30);// 连接FTP服务器if (port == 0) {ftpClient.connect(host);} else {ftpClient.connect(host, port);}// 登陆FTP服务器ftpClient.login(user, pwd);// 中文支持 ,避免图片或文件中文乱码ftpClient.setControlEncoding("GBK"); FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);conf.setServerLanguageCode("zh");// 设置文件类型为二进制(如果从FTP下载或上传的文件是压缩文件的时候,不进行该设置可能会导致获取的压缩文件解压失败)ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {ftpClient.disconnect();Assert.isTrue(false, ERROR_CONN + "用户名或密码错误");} else {log.info("FTP连接成功!");}} catch (Exception e) {log.info("登陆FTP失败,请检查FTP相关配置信息是否正确!" + e);Assert.isTrue(false, ERROR_CONN + e.getMessage());return null;}return ftpClient;}

// deviceId :其实这个是文件名,拼接的,只是我们这以这个id存的文件名,所以用这个
// batch 主要是判断是否需要批量

@Overridepublic List<MultipartFile> getFtpImage(String deviceId, boolean batch) {FTPClient ftpClient = connFtp();String imgUrl = null;List<MultipartFile>  fileList = new ArrayList<>();try {String path = null;String filename = null;//指定文件路径 和 路径下的文件名path = "/5/panorama/";filename = "5_"+deviceId+".jpg";//这一步很重要,主要是类似打开目录,ftpClient.changeWorkingDirectory(path);if(batch){FTPFile[] ftpFiles = ftpClient.listFiles();//获取目录下面文件列表,在下面for (int i =0;i<ftpFiles.length;i++){FTPFile ftpFile = ftpFiles[i];if (ftpFile.getName().equals(filename)) {// 此处表示直接返回到浏览器下载,需要添加参数  HttpServletResponse// response.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(filename, "utf-8"));// 将文件保存到输出流outputStream中//ftpClient.retrieveFile(new String(ftpFile.getName().getBytes("GBK"), "ISO-8859-1"), outputStream);// ftpclient自带方法 将图片转换成 inputStream InputStream inputStream = ftpClient.retrieveFileStream(new String(ftpFile.getName().getBytes("GBK"), "ISO-8859-1"));MultipartFile multipartFile = FileUtil.getMultipartFile(inputStream, filename);fileList.add(multipartFile);inputStream.close();System.out.println("ftp获取图片成功。。。。");}}}else {InputStream inputStream = ftpClient.retrieveFileStream(new String(filename.getBytes("GBK"), "ISO-8859-1"));MultipartFile multipartFile = FileUtil.getMultipartFile(inputStream, filename);//如果想直接上传的话 到这里就可以调用上传方法了fileList.add(multipartFile);inputStream.close();System.out.println("ftp获取图片成功。。。。");}ftpClient.logout();} catch (UnsupportedEncodingException ex) {throw new RuntimeException(ex);} catch (IOException ex) {throw new RuntimeException(ex);}finally {if (ftpClient.isConnected()) {try {ftpClient.disconnect();} catch (IOException ioe) {}}}return fileList;}

获取指定目录下的文件列表

 public List<String> getFileNameList(String ftpDirPath) {FTPClient ftpClient = connFtp();List<String> list = new ArrayList();try {// 通过提供的文件路径获取FTPFile对象列表FTPFile[] files = ftpClient.listFiles(ftpDirPath);for (int i = 0; i < files.length; i++) {FTPFile ftpFile = files[i];if (ftpFile.isFile()) {list.add(ftpFile.getName());}}ftpClient.logout();} catch (IOException e) {log.error("错误" + e);}finally {if (ftpClient.isConnected()) {try {ftpClient.disconnect();} catch (IOException ioe) {}}}return list;}

以下这个方法主要是判断,目录下是否有这个文件,用于某个文件主要判断是否需要录取文件流

/*** 判断ftp服务器文件是否存在** @param ftpClient* @param path* @return* @throws IOException*/private static boolean existFile(FTPClient ftpClient, String path) throws IOException {boolean flag = false;FTPFile[] ftpFileArr = ftpClient.listFiles(path);if (ftpFileArr.length > 0) {flag = true;}return flag;}

后续即是扩展内容,将文件流转换成MultipartFile ,剩下的就是正常上传业务逻辑了

 import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.disk.DiskFileItem;import org.apache.commons.fileupload.disk.DiskFileItemFactory;/*** 获取封装得MultipartFile** @param inputStream inputStream* @param fileName    fileName* @return MultipartFile*/public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {FileItem fileItem = createFileItem(inputStream, fileName);//CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象return new CommonsMultipartFile(fileItem);}/*** FileItem类对象创建** @param inputStream inputStream* @param fileName    fileName* @return FileItem*/public static FileItem createFileItem(InputStream inputStream, String fileName) {FileItemFactory factory = new DiskFileItemFactory(16, null);String textFieldName = "file";FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);int bytesRead = 0;byte[] buffer = new byte[8192];OutputStream os = null;//使用输出流输出输入流的字节try {os = item.getOutputStream();while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {os.write(buffer, 0, bytesRead);}inputStream.close();} catch (IOException e) {log.error("Stream copy exception", e);throw new IllegalArgumentException("文件上传失败");} finally {if (os != null) {try {os.close();} catch (IOException e) {log.error("Stream close exception", e);}}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {log.error("Stream close exception", e);}}}return item;}

总结起来,开发中主要遇到的问题:
1,文件命名不规范,导致拉取失败
2,文件中文乱码,导致找不到
有不懂的或理解不到的,可以留言,相互探讨

相关文章:

手把手教学 Springboot+ftp+下载图片

简单教学&#xff0c;复制即用的Ftp下载图片 引入配置包 <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><dependency><grou…...

LaaS LLM as a service

LaaS LLM as a service 核心构成GPT 产业链如何进行商业化LLM(Large Language Model) 发展和趋势LLM(Large Language Model) 对于行业公司的分层LLM(Large Language Model) 的机遇和挑战 LaaS LLM as a service 核心构成 计算&#xff1a;算力模型&#xff1a;算法输入&…...

数据结构与算法(一)数组的相关概念和底层java实现

一、前言 从今天开始&#xff0c;笔者也开始从0学习数据结构和算法&#xff0c;但是因为这次学习比较捉急&#xff0c;所以记录的内容并不会过于详细&#xff0c;会从基础和底层代码实现以及力扣相关题目去写相关的文章&#xff0c;对于详细的概念并不会过多讲解 二、数组基础…...

歌曲推荐《最佳损友》

最佳损友 陈奕迅演唱歌曲 《最佳损友》是陈奕迅演唱的一首粤语歌曲&#xff0c;由黄伟文作词&#xff0c;Eric Kwok&#xff08;郭伟亮&#xff09;作曲。收录于专辑《Life Continues》中&#xff0c;发行于2006年6月15日。 2006年12月26日&#xff0c;该曲获得2006香港新城…...

多元共进|科技促进艺术发展,助力文化传承

科技发展助力文化和艺术的传播 融合传统与创新&#xff0c;碰撞独特魅力 一起来了解 2023 Google 开发者大会上 谷歌如何依托科技创新 推动艺术与文化连接 传承和弘扬传统文化 自 2011 年成立以来&#xff0c;谷歌艺术与文化致力于提供体验艺术和文化的新方式&#xff0c;从生成…...

Java集合(Collection、Iterator、Map、Collections)概述——Java第十三讲

前言 本讲我们将继续来讲解Java的其他重要知识点——Java集合。Java集合框架是Java编程语言中一个重要的部分,它提供了一套预定义的类和接口,供程序员使用数据结构来存储和操作一组对象。Java集合框架主要包括两种类型:一种是集合(Collection),存储一个元素列表,…...

topscoding主题库模板题

目录 模板题 【模板题】分因数&#xff08;P1101&#xff09; 【模板题】区间素数 III&#xff08;P1113&#xff09; 进制转换 III (任意转任意) &#xff08;P2463&#xff09; AB Problem&#xff08;高精度加法&#xff09; A-B Problem&#xff08;高精度减法&…...

Linux--进程间通讯--FIFO(open打开)

1. 什么是FIFO FIFO命名管道&#xff0c;也叫有名管道&#xff0c;来区分管道pipe。管道pipe只能用于有血缘关系的进程间通信&#xff0c;但通过FIFO可以实现不相关的进程之间交换数据。FIFO是Linux基础文件类型中的一种&#xff0c;但是FIFO文件在磁盘上没有数据块&#xff0c…...

哪里可以了解轻量的工作流引擎?

如果想要实现高效率的办公&#xff0c;可以使用轻量的工作流引擎低代码技术平台。随着工作量日益繁重起来&#xff0c;传统的办公制作方式已经无法满足现实需要的&#xff0c;采用轻量级的表格制作工具&#xff0c;就能在无形中缓解办公压力&#xff0c;创造更高效、灵活、优质…...

lvs负载均衡、LVS集群部署

四&#xff1a;LVS集群部署 lvs给nginx做负载均衡项目 218lvs&#xff08;DR 负载均衡器&#xff09; yum -y install ipvsadm&#xff08;安装这个工具来管理lvs&#xff09; 设置VIP192.168.142.120 创建ipvsadm的文件用来存放lvs的规则 定义策略 ipvsadm -C //清空现有…...

如何应对核心员工提离职?

最近一年互联网行情不好&#xff0c;很多大厂都在裁员&#xff0c;但裁员并不是不要人做事了。原来你这个岗位10个人做&#xff0c;企业有钱赚养得起&#xff0c;现在企业不怎么赚钱了&#xff0c;只能养4个人了。那么会有六个被裁掉。这时候对企业价值最大的4个人会被留下。也…...

建站系列(八)--- 本地开发环境搭建(WNMP)

目录 相关系列文章前言一、准备工作二、Nginx安装三、MySQL安装四、PHP安装及Nginx配置五、总结 相关系列文章 建站系列&#xff08;一&#xff09;— 网站基本常识 建站系列&#xff08;二&#xff09;— 域名、IP地址、URL、端口详解 建站系列&#xff08;三&#xff09;— …...

21天学会C++:Day8----范围for与nullptr

目录 ​编辑 1. 范围for 2. nullptr 1. 范围for 我们在写C语言循环遍历代码的时候&#xff0c;无论是用 for循环&#xff0c;while循环都需要考虑循环的起始条件&#xff0c;循环变量的递增逻辑&#xff0c;循环的结束条件。麻烦不说还可能会出错。 int main() {int arr[]…...

Linux——环境变量

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——环境变量 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;环境变量(environment variables)一般是指在操作系统中用来指定操作…...

Screen的详细全面安装教程及Screen的用法

Screen可以大大提高终端使用效率&#xff0c;是Linux系统管理和运维的必备技能。当我们开启Screen后&#xff0c;只要Screen进程没有终止&#xff0c;其内部运行的会话都可以恢复。即使网络连接中断&#xff0c;用户也可以重新进入已开启的Screen中&#xff0c;对中断的会话进行…...

生成树、Prufer序列的计数问题:0912T1

看到生成树计数&#xff0c;很容易想到生成树计数 然后发现每个点有度数限制&#xff0c;我们可以先考虑枚举每个点的度数&#xff08;也可以是Prufer 序列中的出现次数&#xff09; 假设出现次数为 a a a&#xff0c;可以得出其生成树方案为 n ! ∏ ( a i − 1 ) ! \frac{…...

SQL_牛客网_SQL264_求每个登陆日期的次日留存率

牛客每个人最近的登录日期(五) 牛客每天有很多人登录&#xff0c;请你统计一下牛客每个日期新用户的次日留存率。 有一个登录(login)记录表&#xff0c;简况如下: id user_id client_id date 1 2 1 2020-10-12 2 3 2 2020-10-12 3 1 2 2020-10-…...

Hive 基础知识

目录 1.基础概念1.1 定义1.2 组件1.3 元数据1.4 内部表和外部表 2. Hive与关系型数据库的对比3. Hive 数据存储4. 参考文献 1.基础概念 1.1 定义 Hive是一个基于Hadoop的数据仓库基础设施工具&#xff0c;它可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类SQL查…...

【数据结构】树的基础知识及三种存储结构

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

ABB 3BHB003688R0101接口模块

通信接口&#xff1a;接口模块通常具有多种通信接口&#xff0c;如以太网、串行通信、Modbus、Profibus等&#xff0c;以便与其他设备和系统进行数据交换。 协议支持&#xff1a;它们支持各种通信协议&#xff0c;确保与不同制造商的设备和控制系统兼容。 数据转换和适配&…...

从记事本到IDEA:Java文件编码转换的避雷手册(含BOM字符详解)

从记事本到IDEA&#xff1a;Java文件编码转换的避雷手册&#xff08;含BOM字符详解&#xff09; 在Java开发中&#xff0c;文件编码问题就像一颗定时炸弹&#xff0c;随时可能在最意想不到的时刻引爆。特别是当你的项目需要支持多语言&#xff0c;或者团队中有人习惯使用不同编…...

汽车ECU BootLoader开发:基于CAN总线与MPC57XX系列MCU

汽车ECU BootLoader开发基于CAN总线通信MPC57XX系列MCU bootloader开发 文档54页 在汽车电子领域&#xff0c;ECU&#xff08;Electronic Control Unit&#xff09;的重要性不言而喻&#xff0c;而BootLoader则是ECU中关键的一环。今天咱们就来聊聊基于CAN总线通信&#xff0c…...

3大突破!OptiScaler如何让老旧硬件焕发新生

3大突破&#xff01;OptiScaler如何让老旧硬件焕发新生 【免费下载链接】OptiScaler DLSS replacement for AMD/Intel/Nvidia cards with multiple upscalers (XeSS/FSR2/DLSS) 项目地址: https://gitcode.com/GitHub_Trending/op/OptiScaler 当你的AMD显卡遇见只支持DL…...

Qwen2.5-VL-Ollama效果对比:vs Qwen2-VL在图表理解与定位精度提升

Qwen2.5-VL-Ollama效果对比&#xff1a;vs Qwen2-VL在图表理解与定位精度提升 1. 引言&#xff1a;从Qwen2-VL到Qwen2.5-VL的进化 如果你之前用过Qwen2-VL&#xff0c;可能会觉得它已经很强了——能看懂图片&#xff0c;能回答问题&#xff0c;基本的多模态任务都能搞定。但用…...

FastAPI JWT刷新令牌:安全存储的完整指南

FastAPI JWT刷新令牌&#xff1a;安全存储的完整指南 【免费下载链接】fastapi FastAPI framework, high performance, easy to learn, fast to code, ready for production 项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi 在前100个字内&#xff0c;FastAP…...

【开题答辩全过程】以 基于Java的影视设备维修评估系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…...

突破学术翻译障碍:Zotero PDF Translate文献阅读效率提升指南

突破学术翻译障碍&#xff1a;Zotero PDF Translate文献阅读效率提升指南 【免费下载链接】zotero-pdf-translate 支持将PDF、EPub、网页内容、元数据、注释和笔记翻译为目标语言&#xff0c;并且兼容20多种翻译服务。 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-p…...

嵌入式开发中PlantUML图表的工程化应用

嵌入式开发中PlantUML图表的工程化应用指南1. 嵌入式文档工具概述在嵌入式系统开发过程中&#xff0c;系统架构图和设计文档是工程师沟通需求、梳理逻辑的核心工具。传统拖拽式绘图工具存在效率低下、维护困难等问题&#xff0c;而基于代码生成图表的PlantUML技术为嵌入式开发文…...

小白也能懂!CosyVoice2-0.5B API调用全攻略,快速生成克隆语音

小白也能懂&#xff01;CosyVoice2-0.5B API调用全攻略&#xff0c;快速生成克隆语音 1. 准备工作&#xff1a;认识CosyVoice2-0.5B CosyVoice2-0.5B是阿里开源的一款强大的语音克隆工具&#xff0c;它能让你用短短3-10秒的参考音频&#xff0c;就能克隆出几乎一模一样的声音…...

PSO-Transformer分类预测Matlab代码:基于粒子群优化算法优化Transfor...

PSO-Transformer分类 Matlab代码 基于粒子群优化算法(PSO)优化Transformer的数据分类预测(可以更换为单、多变量时序预测/回归&#xff0c;前私我)&#xff0c;Matlab代码&#xff0c;可直接运行&#xff0c;适合小白新手 程序已经调试好&#xff0c;无需更改代码替换数据集即可…...