异步处理multipartFile,找不到临时文件,java.io.FileNotFoundException:xxx.tmp (系统找不到指定的文件。)

文章目录

  • 前言
  • 一、问题描述
  • 二、解决方案
    • 1.将 MultipartFile 文件转换为流
    • 2.将 MultipartFile 文件转换为字节数组
  • 总结


异步处理multipartFile,找不到临时文件,java.io.FileNotFoundException:xxx.tmp (系统找不到指定的文件。)_第1张图片

前言

需求:之前做 multipartFile 文件上传处理时是同步的,现要将同步处理改为异步处理。


提示:以下是本篇文章正文内容,下面案例可供参考

一、问题描述

  • 问题:当同步改为多线程处理或者加上@Async 异步处理时,会报错:java.io.FileNotFoundException 系统找不到指定的文件
java.io.FileNotFoundException: C:\Users\minis\AppData\Local\Temp\tomcat.8973262732558840642.8011\work\Tomcat\localhost\ROOT\upload_8b7dee27_e34d_47e9_b755_cea7d688aa94_00000000.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:194)
	at org.apache.catalina.core.ApplicationPart.getInputStream(ApplicationPart.java:100)
	at com.alpari.web.service.impl.UserServiceImpl.asyncFile(UserServiceImpl.java:22)
......
  • 代码:异步处理 MultipartFile
@Autowired
private UserService userService;

@PostMapping("/demoUpload")
public String demoUpload(MultipartFile file) {
    // 异步处理 file
    userService.asyncFile(file);
    return "success";
}

// 注意要在启动类上加 @EnableAsync
@Async
@Override
public void asyncFile(MultipartFile file) {
    try {
    	// 这边睡了一会是模拟文件相关操作的时间
        Thread.sleep(200);
        file.getInputStream();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  • 原因:异步执行,当主线程执行完,临时文件会被清空,而此时异步线程并未执行完

前端传过来的文件会存储到临时文件夹中,当我们的方法是异步执行时(即加上 @Async 注解或者在多线程中执行),主线程结束时,临时文件就会被清空,而异步线程未结束,所以在使用文件时就会报找不到文件错误。

二、解决方案

1.将 MultipartFile 文件转换为流

@PostMapping("/demoUpload")
public String demoUpload(MultipartFile file) {
    // 异步处理 file
    try {
        userService.asyncFileInputStream(file.getInputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "success";
}

@Async
@Override
public void asyncFileInputStream(InputStream inputStream) {
    try {
        Thread.sleep(200);
        System.out.println(inputStream);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
    	// 关闭流
        IOUtils.closeQuietly(inputStream);
    }
}

2.将 MultipartFile 文件转换为字节数组

@PostMapping("/demoUpload")
public String demoUpload(MultipartFile file) {
    // 异步处理 file
    try {
    	// 转换成String是为了方便接收 MultipartFile[],可以转换成 String[]
        String base64Bytes = Base64.getEncoder().encodeToString(file.getBytes());
        userService.asyncFileBase64Bytes(base64Bytes);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "success";
}

@Async
@Override
public void asyncFileBase64Bytes(String base64Bytes) {
    try {
        Thread.sleep(200);
        // 转换为流,使用完毕后关闭,此代码片段省略...
        ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(base64Bytes));
        System.out.println(inputStream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

总结

爱是理解,爱是等待,爱是包容,爱是不强求。

你可能感兴趣的:(错误实例,java,开发语言)