MultipartFile与File的一些事
摘要:某段时间碰到了中转文件的需求,需要使用HttpClient中转一下文件,在实现这个需求的过程中就用得到了MultipartFile与File。
本文分享自华为云社区《MultipartFile与File的一些事》,作者: Copy工程师 。
前言
某段时间碰到了中转文件的需求,需要使用HttpClient中转一下文件,过程为:
在实现这个需求的过程中就用得到了MultipartFile与File,而且我对前一个也不是很熟悉。记录一下
什么是MultipartFile
MultipartFile是spring类型,代表HTML中form data方式上传的文件,包含二进制数据+文件名称。【来自百度知道】
MultipartFile 与 File 的 互相转换
1. File转MultipartFile
(1):使用org.springframework.mock.web.MockMultipartFile 需要导入spring-test.jar
- public static void main(String[] args) throws Exception {
- String filePath = "F:\\test.txt";
- File file = new File(filePath);
- FileInputStream fileInputStream = new FileInputStream(file);
- // MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream)
- // 其中originalFilename,String contentType 旧名字,类型 可为空
- // ContentType.APPLICATION_OCTET_STREAM.toString() 需要使用HttpClient的包
- MultipartFile multipartFile = new MockMultipartFile("copy"+file.getName(),file.getName(),ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream);
- System.out.println(multipartFile.getName()); // 输出copytest.txt
- }
(2):使用CommonsMultipartFile
- public static void main(String[] args) throws Exception {
- String filePath = "F:\\test.txt";
- File file = new File(filePath);
- // 需要导入commons-fileupload的包
- FileItem fileItem = new DiskFileItem("copyfile.txt", Files.probeContentType(file.toPath()),false,file.getName(),(int)file.length(),file.getParentFile());
- byte[] buffer = new byte[4096];
- int n;
- try (InputStream inputStream = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()){
- while ( (n = inputStream.read(buffer,0,4096)) != -1){
- os.write(buffer,0,n);
- }
- //也可以用IOUtils.copy(inputStream,os);
- MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
- System.out.println(multipartFile.getName());
- }catch (IOException e){
- e.printStackTrace();
- }
- }
2. MultipartFile转File
(1):使用File转MultipartFile的逆过程
你在看这个代码的时候会觉得很熟悉,是的这个就是File转MultipartFile的逆转过程,这个方法会在根目录生成一个文件,需要删除该文件。
- public static void main(String[] args) throws Exception {
- int n;
- // 得到MultipartFile文件
- MultipartFile multipartFile = getFile();
- File f = null;
- // 输出文件的新name 就是指上传后的文件名称
- System.out.println("getName:"+multipartFile.getName());
- // 输出源文件名称 就是指上传前的文件名称
- System.out.println("Oriname:"+multipartFile.getOriginalFilename());
- // 创建文件
- f = new File(multipartFile.getOriginalFilename());
- try ( InputStream in = multipartFile.getInputStream(); OutputStream os = new FileOutputStream(f)){
- // 得到文件流。以文件流的方式输出到新文件
- // 可以使用byte[] ss = multipartFile.getBytes();代替while
- byte[] buffer = new byte[4096];
- while ((n = in.read(buffer,0,4096)) != -1){
- os.write(buffer,0,n);
- }
- // 读取文件第一行
- BufferedReader bufferedReader = new BufferedReader(new FileReader(f));
- System.out.println(bufferedReader.readLine());
- // 输出路径
- bufferedReader.close();
- }catch (IOException e){
- e.printStackTrace();
- }
- // 输出file的URL
- System.out.println(f.toURI().toURL().toString());
- // 输出文件的绝对路径
- System.out.println(f.getAbsolutePath());
- // 操作完上的文件 需要删除在根目录下生成的文件
- File file = new File(f.toURI());
- if (file.delete()){
- System.out.println("删除成功");
- }else {
- System.out.println("删除失败");
- }
- }
- /**
- *
- * @Description 返回MultipartFile文件
- * @return org.springframework.web.multipart.MultipartFile
- * @date 2019/1/5 11:08
- * @auther dell
- */
- public static MultipartFile getFile() throws IOException {
- String filePath = "F:\\test.txt";
- File file = new File(filePath);
- FileItem fileItem = new DiskFileItem("copyfile.txt", Files.probeContentType(file.toPath()),false,file.getName(),(int)file.length(),file.getParentFile());
- byte[] buffer = new byte[4096];
- int n;
- try (InputStream inputStream = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()){
- while ( (n = inputStream.read(buffer,0,4096)) != -1){
- os.write(buffer,0,n);
- }
- //也可以用IOUtils.copy(inputStream,os);
- MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
- System.out.println(multipartFile.getName());
- return multipartFile;
- }catch (IOException e){
- e.printStackTrace();
- }
- return null;
- }
(2):使用transferTo (本质上还是使用了流 只不过是封装了步骤)
会生成文件,最后不需要文件要删除
- public static void main(String[] args) throws Exception {
- String path = "F:\\demo\\";
- File file = new File(path,"demo.txt");
- // 得到MultipartFile文件
- MultipartFile multipartFile = getFile();
- /*byte[] ss = multipartFile.getBytes();
- OutputStream os = new FileOutputStream(file);
- os.write(ss);
- os.close();*/
- multipartFile.transferTo(file);
- // 读取文件第一行
- BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
- System.out.println(bufferedReader.readLine());
- // 输出绝对路径
- System.out.println(file.getAbsolutePath());
- bufferedReader.close();
- // 操作完上的文件 需要删除在根目录下生成的文件
- if (file.delete()){
- System.out.println("删除成功");
- }else {
- System.out.println("删除失败");
- }
- }
- /**
- *
- * @Description 返回MultipartFile文件
- * @return org.springframework.web.multipart.MultipartFile
- * @date 2019/1/5 11:08
- * @auther dell
- */
- public static MultipartFile getFile() throws IOException {
- String filePath = "F:\\test.txt";
- File file = new File(filePath);
- FileItem fileItem = new DiskFileItem("copyfile.txt", Files.probeContentType(file.toPath()),false,file.getName(),(int)file.length(),file.getParentFile());
- byte[] buffer = new byte[4096];
- int n;
- try (InputStream inputStream = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()){
- while ( (n = inputStream.read(buffer,0,4096)) != -1){
- os.write(buffer,0,n);
- }
- //也可以用IOUtils.copy(inputStream,os);
- MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
- System.out.println(multipartFile.getName());
- return multipartFile;
- }catch (IOException e){
- e.printStackTrace();
- }
- return null;
- }
(3):使用FileUtils.copyInputStreamToFile()
也是会生成文件,到最后也是要删除文件
- public static void main(String[] args) throws Exception {
- String path = "F:\\demo\\";
- File file = new File(path,"demo.txt");
- // 得到MultipartFile文件
- MultipartFile multipartFile = getFile();
- // 把流输出到文件
- FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),file);
- // 读取文件第一行
- BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
- System.out.println(bufferedReader.readLine());
- // 输出绝对路径
- System.out.println(file.getAbsolutePath());
- bufferedReader.close();
- // 操作完上的文件 需要删除在根目录下生成的文件
- if (file.delete()){
- System.out.println("删除成功");
- }else {
- System.out.println("删除失败");
- }
- }
- /**
- *
- * @Description 返回MultipartFile文件
- * @return org.springframework.web.multipart.MultipartFile
- * @date 2019/1/5 11:08
- * @auther dell
- */
- public static MultipartFile getFile() throws IOException {
- String filePath = "F:\\test.txt";
- File file = new File(filePath);
- FileItem fileItem = new DiskFileItem("copyfile.txt", Files.probeContentType(file.toPath()),false,file.getName(),(int)file.length(),file.getParentFile());
- byte[] buffer = new byte[4096];
- int n;
- try (InputStream inputStream = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()){
- while ( (n = inputStream.read(buffer,0,4096)) != -1){
- os.write(buffer,0,n);
- }
- //也可以用IOUtils.copy(inputStream,os);
- MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
- System.out.println(multipartFile.getName());
- return multipartFile;
- }catch (IOException e){
- e.printStackTrace();
- }
- return null;
- }
4:强转类型
- CommonsMultipartFile commonsmultipartfile = (CommonsMultipartFile) multipartFile;
- DiskFileItem diskFileItem = (DiskFileItem) commonsmultipartfile.getFileItem();
- File file = diskFileItem.getStoreLocation();
这种强转你获得的file只是一个空壳
你能获取的也只有这个F:\upload_edfce39f_2894_4b66_b865_d5fb8636bdf3_00000000.tmp 网上有说会在根目录生成临时文件的,从tmp也可以看出来是个临时文件,但是我试了好几次啥都没找到。。。。直接获取这个file读取内容也是会报文件找不到的 这是必然的 当然也有在spring配置文件配置CommonsMultipartResolver的 这就感觉很麻烦了。。。。
但是我们可以看一下diskFileItem 看下图 是不是很熟悉了,从diskFileItem可以获取文件流,其实你看了源码你就知道获取文件流都是从这里获取的。剩下的就好办了 我就不赘述了/。
在使用临时文件的时候可以使用缓冲区创建临时文件
- // createTempFile(String prefix, String suffix)
- // prefix 文件名 suffix 文件格式
- // 默认是tmp格式 C:\Users\dell\AppData\Local\Temp\tmp8784723057512789016.tmp
- File file =File.createTempFile("tmp", null);
- // txt格式 C:\Users\dell\AppData\Local\Temp\tmp2888293586594052933.txt
- File file =File.createTempFile("tmp", ".txt");
HttpClient构建上传文件参数并实现中转文件
这里不自己给例子了,参考了其他博客的代码
- // 获取文件名称
- String fileName = file.getOriginalFilename();
- HttpPost httpPost = new HttpPost(url);
- // 创建文件上传实体
- MultipartEntityBuilder builder = MultipartEntityBuilder.create();
- builder.addBinaryBody("file", file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);
- builder.addTextBody("filename", fileName);
- HttpEntity entity = builder.build();
- httpPost.setEntity(entity);
- HttpResponse response = httpClient.execute(httpPost);// 执行提交
执行提交之后你会发现你上传的文件名会出现中文乱码
我使用的解决办法是:
- //设置模式为RFC6532
- builder.setMode(HttpMultipartMode.RFC6532);
MultipartFile与File的一些事的更多相关文章
- [转]spring MultipartFile 转 File
原文地址:https://www.jianshu.com/p/6cf99d39e170 File.createTempFile(String prefix, String suffix); 创建一个临 ...
- Springmvc 上传文件MultipartFile 转File
转自:http://blog.csdn.net/boneix/article/details/51303207 业务场景:ssm框架 上传文件到应用服务器过程中要传到专有的文件服务器并返回url进行其 ...
- MultipartFile 转换为File
选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 . MultipartFile multipartFile; File fil ...
- Multipartfile与File类型相互转换
特殊情况下需要做转换 1.M转F File file = new File(path); FileUtils.copyInputStreamToFile(multipartFile.getInputS ...
- SpringMVC 上传文件 MultipartFile 转为 File
在使用 SpringMVC 上传文件时,接收到的文件格式为 MultipartFile,但是在很多场景下使用都需要File格式的文件,记录下以便日后使用. 以下mFile为MultipartFile文 ...
- spring MVC 的MultipartFile转File??
MultipartFile file = xxx; CommonsMultipartFile cf= (CommonsMultipartFile)file; DiskF ...
- spring MVC 的MultipartFile转File读取
转自:http://www.cnblogs.com/hahaxiaoyu/p/5102900.html 第一种方法: MultipartFile file = xxx; Commo ...
- 关于Java数据转存的中MultipartFile转File的问题(转)
转自http://www.cnblogs.com/zuoxiaoxia/p/6116942.html 错误背景:由于文件储存在第三方的服务器上,所有需要讲将接收到MultipartFile文件 转换为 ...
- Required MultipartFile parameter 'file' is not present error
<input type=“file”> 中的name 与id 属性 与 addbanner(@RequestParam("file") MultipartFile ...
- springmvc 中将MultipartFile转为file,springboot 注入CommonsMultipartResolver
第一种方法: MultipartFile file = xxx; CommonsMultipartFile cf= (CommonsMultipartFile)file; DiskFileItem f ...
随机推荐
- 2023云栖大会议程&体验攻略
2023云栖大会倒计时1天 将围绕"计算,为了无法计算的价值" 为大家带来一场有用.有趣科技盛宴 City Walk 不如云栖Walk 今日,送上一份参会指南 给所有参会者& ...
- html-7(JavaScript-1)
放在函数里面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <ti ...
- Welcome to YARP - 7.目标健康检查
目录 Welcome to YARP - 1.认识YARP并搭建反向代理服务 Welcome to YARP - 2.配置功能 2.1 - 配置文件(Configuration Files) 2.2 ...
- 关于微信小程序中如何实现数据可视化-echarts动态渲染
移动端设备中,难免会涉及到数据的可视化展示.数据统计等等,本篇主要讲解原生微信小程序中嵌入echarts并进行动态渲染,实现数据可视化功能. 基础使用 首先在GitHub上下载echarts包 地址: ...
- 4. Shell 循环语句
重点: 条件测试. read. Shell 环境配置. case. for. find. xargs. gzip,bzip2,xz. tar. sed. 1)循环 1.1)循环执行介绍 将某代码段重复 ...
- 快速下载vscode、git
在官网下载vscode太慢,解决方式: http://vscode.cdn.azure.cn/stable/ea3859d4ba2f3e577a159bc91e3074c5d85c0523/VSCod ...
- [ARC158D] Equation
Problem Statement You are given a positive integer $n$, and a prime number $p$ at least $5$. Find a ...
- PyTorch 中自定义数据集的读取方法
显然我们在学习深度学习时,不能只局限于通过使用官方提供的MNSIT.CIFAR-10.CIFAR-100这样的数据集,很多时候我们还是需要根据自己遇到的实际问题自己去搜集数据,然后制作数据集(收集数据 ...
- 【UniApp】-uni-app-传递数据
前言 好,经过上个章节的介绍完毕之后,了解了一下 uni-app-路由 那么了解完了uni-app-路由之后,这篇文章来给大家介绍一下 uni-app-路由传递数据 路由传参怎么传,是不是可以从 A ...
- Java8函数式编程应用
我们经常提到,Java8是革命性的一个版本,原因就是正式引入了函数式编程,那Java的函数式编程在实际应用中到底有什么用呢?结合实际的应用,我整理出了函数式在Java的几个经典用途. 缓求值 惰性求值 ...