MultipartFile上传文件异步处理时的java.io.FileNotFoundException()

  本篇文章为你整理了MultipartFile上传文件异步处理时的java.io.FileNotFoundException()的详细内容,包含有 MultipartFile上传文件异步处理时的java.io.FileNotFoundException,希望能帮助你了解 MultipartFile上传文件异步处理时的java.io.FileNotFoundException。

  1-1 需求

  前端上传Word文档,后端将接收到的Word文档①上传到文件服务器②将Word转为Pdf。

  1-2 方案

  因为Word转Pdf的耗时较长,为了及时给到前端返回信息,在将文件上传到文件服务器后,异步将Word转为Pdf。

  创建一个SpringBoot项目。

  

 1 package com.trent.upload.action;

 

   3 import com.trent.upload.service.UploadService;

   4 import org.springframework.web.bind.annotation.PostMapping;

   5 import org.springframework.web.bind.annotation.RequestMapping;

   6 import org.springframework.web.bind.annotation.RestController;

   7 import org.springframework.web.multipart.MultipartFile;

   9 import javax.annotation.Resource;

  11 /**

  12 * 上传文件的Action层

  14 * @author Hutao

  15 * @date 2022/8/16 15:10

  16 * @since 1.0

  17 */

  18 @RequestMapping

  19 @RestController

  20 public class UploadAction {

  22 @Resource

  23 private UploadService uploadService;

  25 /**

  26 * 文件上传接口

  27 * @param multipartFile 上传的文件

  28 * @return 上传结果

  30 * @author Hutao

  31 * @date 2022/8/16 15:10

  32 * @since 1.0

  33 */

  34 @PostMapping("/upload")

  35 public String upload(MultipartFile multipartFile) {

  37 uploadService.dealFile(multipartFile);

  38 return "上传成功";

  40 }

 

  

  

 1 package com.trent.upload.service;

 

   3 import org.springframework.stereotype.Service;

   4 import org.springframework.web.multipart.MultipartFile;

   6 import java.util.concurrent.ExecutorService;

   7 import java.util.concurrent.Executors;

   8 import java.util.concurrent.TimeUnit;

  10 /**

  11 * 上传文件的Service层

  13 * @author Hutao

  14 * @date 2022/8/16 15:11

  15 * @since 1.0

  16 */

  17 @Service

  18 public class UploadService {

  20 /**

  21 * 线程池(仅用于简单演示)

  22 */

  23 private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool();

  25 /**

  26 * 处理上传的文件

  27 * @param multipartFile 上传的文件

  29 * @author Hutao

  30 * @date 2022/8/16 15:13

  31 * @since 1.0

  32 */

  33 public void dealFile(MultipartFile multipartFile) {

  34 // 模拟上传Word文件到文件服务器

  35 System.out.println("上传Word文件到文件服务器");

  37 // 异步将Word文件转为Pdf

  38 EXECUTOR_SERVICE.execute(() - convertToPdf(multipartFile));

  41 /**

  42 * 将文件转为Pdf

  43 * @param multipartFile 待转换的源文件

  45 * @author Hutao

  46 * @date 2022/8/16 15:13

  47 * @since 1.0

  48 */

  49 public void convertToPdf(MultipartFile multipartFile) {

  50 try {

  52 // 获取上传的文件的输入流,用于转为Pdf,如果成功获取到了输入流,就认为转Pdf成功

  53 multipartFile.getInputStream();

  54 System.out.println("Word转Pdf成功");

  56 } catch (Exception e) {

  57 System.out.println("Word转Pdf失败");

  58 e.printStackTrace();

  61 }

 

  3-1 问题描述

  以上是一个简单的演示,在实际的项目中,会偶现如下异常。

  

上传Word文件到文件服务器

 

  Word转Pdf失败

  java.io.FileNotFoundException: C:\Users\Liujl\AppData\Local\Temp\tomcat.8080.567748920478140755\work\Tomcat\localhost\ROOT\upload_8e27d0a7_9cf4_4f8a_aecc_ea051653749e_00000006.tmp (系统找不到指定的文件。)

   at java.io.FileInputStream.open0(Native Method)

   at java.io.FileInputStream.open(FileInputStream.java:195)

   at java.io.FileInputStream. init (FileInputStream.java:138)

   at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.getInputStream(DiskFileItem.java:198)

   at org.apache.catalina.core.ApplicationPart.getInputStream(ApplicationPart.java:100)

   at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.getInputStream(StandardMultipartHttpServletRequest.java:254)

   at com.trent.upload.service.UploadService.convertToPdf(UploadService.java:57)

   at com.trent.upload.service.UploadService.lambda$dealFile$0(UploadService.java:43)

   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

   at java.lang.Thread.run(Thread.java:748)

 

  意思是找不到某个临时文件。

  3-2 问题复现

  在UploadService类的51行添加如下代码,可保证每次上传文件操作都会出现3-1中的异常。

  

 1 public void convertToPdf(MultipartFile multipartFile) {

 

   2 try {

   3 TimeUnit.MILLISECONDS.sleep(10);

   4 // 获取上传的文件的输入流,用于转为Pdf,如果成功获取到了输入流,就认为转Pdf成功

   5 multipartFile.getInputStream();

   6 System.out.println("Word转Pdf成功");

   8 } catch (Exception e) {

   9 System.out.println("Word转Pdf失败");

  10 e.printStackTrace();

  12 }

 

  3-3 原因分析

  1.后台用MultipartFile接收到前端传来的文件后,会在本地生成一个临时文件,以.tmp结尾;

  2.MultipartFile对应的临时文件的生命周期是一个请求会话,会话结束,MultipartFile的临时文件会被自动清理;

  3.因为将文件转为Pdf的方法是在请求主线程之外的另一个线程中执行的,所以不在请求会话的生命周期内。如果请求会话的主线程结束了(将请求结果返回给前端了),这个请求传来的MultipartFile的临时文件就会被清理掉,在将文件转Pdf的线程中就拿不到MultipartFile对应的临时文件,也就获取不到对应的输入流,故抛出FileNotFoundException。

  四.解决方案

  主线程在用MultipartFile接收到前端传来文件后,立即将MultipartFile保存为本地文件。将文件转Pdf时,使用保存在本地的文件,转换完成后,删除本地文件。

  注:

  1.可使用MultipartFile的transferTo方法将MultipargFile转为本地文件,但需要注意,transferTo方法被调用后,也会删除MultipartFile对应的临时文件;

  2.在使用transferTo的时候可能会出现绝对路径和相对路径的问题;

  3.鉴于1.2中transferTo方法的局限性,建议手动获取MultipartFile的输入流,然后写到本地文件中。可以使用Hutool的FileUtils.copyInputStreamToFile(final InputStream source, final File destination)方法;

  4.本地文件使用完成后,务必删除本地文件,避免服务器硬盘被占满。

  以上就是MultipartFile上传文件异步处理时的java.io.FileNotFoundException()的详细内容,想要了解更多 MultipartFile上传文件异步处理时的java.io.FileNotFoundException的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: