聊聊MultipartFile与File的一些事儿

作者:sdut菜鸟 时间:2023-06-27 03:07:00 

前言

前段时间碰到了中转文件的需求,需要使用HttpClient中转一下文件,过程为:

聊聊MultipartFile与File的一些事儿

在实现这个需求的过程中就用得到了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;
   }

3:强转类型


CommonsMultipartFile commonsmultipartfile = (CommonsMultipartFile) multipartFile;
DiskFileItem diskFileItem = (DiskFileItem) commonsmultipartfile.getFileItem();
File file = diskFileItem.getStoreLocation();

这种强转你获得的file只是一个空壳

聊聊MultipartFile与File的一些事儿

你能获取的也只有这个F:\upload_edfce39f_2894_4b66_b865_d5fb8636bdf3_00000000.tmp 网上有说会在根目录生成临时文件的,从tmp也可以看出来是个临时文件,但是我试了好几次啥都没找到。。。。

直接获取这个file读取内容也是会报文件找不到的 这是必然的 当然也有在spring配置文件配置CommonsMultipartResolver的 这就感觉很麻烦了。。。。

但是我们可以看一下diskFileItem 看下图 是不是很熟悉了,从diskFileItem可以获取文件流,其实你看了源码你就知道获取文件流都是从这里获取的。剩下的就好办了 我就不赘述了/。

聊聊MultipartFile与File的一些事儿

在使用临时文件的时候可以使用缓冲区创建临时文件


//  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);// 执行提交

执行提交之后你会发现你上传的文件名会出现中文乱码

这里参考

HttpClient上传文件中文名乱码 该文章详细说明了为什么会乱码以及怎么解决

我使用的解决办法是:


//设置模式为RFC6532
builder.setMode(HttpMultipartMode.RFC6532);

来源:https://blog.csdn.net/sdut406/article/details/85647982

标签:MultipartFile,File
0
投稿

猜你喜欢

  • Java中如何快速构建项目脚手架的实现

    2023-10-30 03:37:50
  • java多线程抓取铃声多多官网的铃声数据

    2023-12-18 23:20:05
  • 浅谈c# 浮点数计算

    2023-08-04 22:10:09
  • Android自定义View画圆功能

    2023-05-18 10:47:24
  • Java设计模式之观察者模式_动力节点Java学院整理

    2022-01-14 12:27:47
  • C#微信公众号开发之消息处理

    2023-11-10 01:10:53
  • SpringBoot解析指定Yaml配置文件的实现过程

    2023-05-22 19:09:23
  • 详解Spring中的@PropertySource注解使用

    2023-05-05 06:40:15
  • java操作excel表格详解

    2021-08-20 14:35:46
  • Android使用自定义View实现360手机卫士波浪球进度的效果

    2023-03-21 19:18:34
  • 基于Java手写一个好用的FTP操作工具类

    2021-06-05 20:10:18
  • 详解ASP.NET中Identity的身份验证代码

    2022-05-20 04:43:48
  • Android进阶事件分发机制解决事件冲突

    2021-08-22 06:12:34
  • 浅谈Java(SpringBoot)基于zookeeper的分布式锁实现

    2023-11-16 08:14:56
  • 关于Mybatis与JPA的优缺点说明

    2023-08-23 22:28:33
  • Java 实战项目锤炼之小区物业管理系统的实现流程

    2021-07-17 09:24:01
  • C#使用TimeSpan时间计算的简单实现

    2023-10-06 07:25:55
  • 详解Spring整合Ehcache管理缓存

    2022-02-10 00:50:17
  • VS2015为console.readkey添加代码片段的方法

    2023-11-15 05:23:41
  • android实现点击按钮控制图片切换

    2022-10-16 02:38:55
  • asp之家 软件编程 m.aspxhome.com