摘要:某段时间碰到了中转文件的需求,需要使用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的一些事的更多相关文章

  1. [转]spring MultipartFile 转 File

    原文地址:https://www.jianshu.com/p/6cf99d39e170 File.createTempFile(String prefix, String suffix); 创建一个临 ...

  2. Springmvc 上传文件MultipartFile 转File

    转自:http://blog.csdn.net/boneix/article/details/51303207 业务场景:ssm框架 上传文件到应用服务器过程中要传到专有的文件服务器并返回url进行其 ...

  3. MultipartFile 转换为File

    选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 . MultipartFile multipartFile; File fil ...

  4. Multipartfile与File类型相互转换

    特殊情况下需要做转换 1.M转F File file = new File(path); FileUtils.copyInputStreamToFile(multipartFile.getInputS ...

  5. SpringMVC 上传文件 MultipartFile 转为 File

    在使用 SpringMVC 上传文件时,接收到的文件格式为 MultipartFile,但是在很多场景下使用都需要File格式的文件,记录下以便日后使用. 以下mFile为MultipartFile文 ...

  6. spring MVC 的MultipartFile转File??

    MultipartFile file = xxx;         CommonsMultipartFile cf= (CommonsMultipartFile)file;         DiskF ...

  7. spring MVC 的MultipartFile转File读取

    转自:http://www.cnblogs.com/hahaxiaoyu/p/5102900.html 第一种方法:   MultipartFile file = xxx;         Commo ...

  8. 关于Java数据转存的中MultipartFile转File的问题(转)

    转自http://www.cnblogs.com/zuoxiaoxia/p/6116942.html 错误背景:由于文件储存在第三方的服务器上,所有需要讲将接收到MultipartFile文件 转换为 ...

  9. Required MultipartFile parameter 'file' is not present error

    <input type=“file”>  中的name 与id 属性 与  addbanner(@RequestParam("file") MultipartFile ...

  10. springmvc 中将MultipartFile转为file,springboot 注入CommonsMultipartResolver

    第一种方法: MultipartFile file = xxx; CommonsMultipartFile cf= (CommonsMultipartFile)file; DiskFileItem f ...

随机推荐

  1. VM虚拟机在添加虚拟硬盘后无法boot的解决方案

    今天本想自己配一个mini Linux系统,但是在给系统增加一块硬盘的时候,发现出现以下问题 CentOS打不开(其实经过很久也能进去,但是指令全部失效) 由于不知道原因最后就重装了系统,奇怪的是,重 ...

  2. 基于Echart的前端可视化

    GitHub 上有许多关于低代码自助可视化的项目,前端使用 Vue 和 ECharts 的示例.以下是一些可能符合你要求的项目: DataV: 项目链接:DataV 描述:DataV 是一款基于 Vu ...

  3. testre

    f5看到关键代码判断 猜测这是flag或者是加密后的结果,直接将其当作flag答案不对,所以猜测为加密后的结果,然后再通过其他函数了解 跟进第一个函数发现编码表 本来想试试base解密,可是当时只试了 ...

  4. 12k Star、40万+开发者信赖的开源商城系统

    前几天,有位读者问我有没有什么优秀的国产开源电商平台,他要拿来接单赚外快.我一听这话,精神头就来了. 所以,今天 HelloGitHub 就给大家找来了一款自用.二开都很方便的国产开源商城系统--CR ...

  5. [FJOI2017]矩阵填数 (容斥原理)

    题目传送门 现在看来熊猫杯的J题原来是个容斥套路题,按照值域排序后根据值域划分方块数,枚举子集容斥计算即可. #include<cstdio> #include<algorithm& ...

  6. AutoCAD ObjectARX 二次开发(2020版)--4,使用ARX向导创建CAD二次开发项目(编程框架)--

    手动创建ObjectARX应用程序非常麻烦,在此步骤中,将介绍ObjectARX向导. 在这里,我们将使用ObjectARX向导创建我们的ObjectARX应用程序. 本节的程序的需求是,接收CAD用 ...

  7. 25 个超棒的 Python 脚本合集

    Python是一种功能强大且灵活的编程语言,拥有广泛的应用领域.下面是一个详细介绍25个超棒的Python脚本合集: 1. 网络爬虫:使用Python可以轻松编写网络爬虫,从网页中提取数据并保存为结构 ...

  8. SQL执行insert into后返回主键ID

    1 select @@identity 2 select SCOPE_IDENTITY() 3 select IDENT_CURRENT('table') 注解:@@IDENTITY 返回当前会话的所 ...

  9. [ABC261E] Many Operations

    Problem Statement We have a variable \(X\) and \(N\) kinds of operations that change the value of \( ...

  10. FolkMQ 内存型消息中间件,v1.0.21 发布

    简介 采用 "多路复用" + "内存运行" + "快照持久化" + "Broker 集群模式"(可选)+ 基于 Sock ...