当前位置: 首页 > 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;确保与不同制造商的设备和控制系统兼容。 数据转换和适配&…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...