java异步上传文件出现java.io.FileNotFoundException异常

最近做了一个异步上传解析excel功能,最后联调时偶发出现了FileNotFoundException异常:

1、现象

在这里插入图片描述

java.io.FileNotFoundException: /tmp/tomcat.4469822161725136903.8080/work/Tomcat/localhost/ROOT/upload_4bed117f_51fb_4d70_b307_fc00edd99e4a_00000029.tmp (No such file or directory)
	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 org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.getBytes(StandardMultipartHttpServletRequest.java:245)

大致代码如下:


    @PostMapping(value = "/asyncImport")
    public Boolean asyncImport(@RequestParam("file") MultipartFile file) {
        try {
            //异步接口
            importService.asyncImport(file.getInputStream());
            return true;
        } catch (IOException e) {
            throw new RuntimeException("出现错误");
        }
    }


  @Async
    public String asyncImport(InputStream inputStream) {
        //执行操作
        return "ok";

    }


2.原因:

这个时候会有概率抛出java.io.FileNotFoundException:

因为 Service方法为异步方法, controller会立马执行完成, 完成后便会关闭IO流, 最后会导致文件找不到

3.解决方案

1.得到MultipartFile的byte数组,将byte数组传入service,租后转换成IO流

byte[] bytes = MultipartFile.getBytes();

优点:比较快,比较方便

缺点:大文件是可能为导致频繁fullgc,甚至是OOM

2.将MultipartFile写入到一个临时文件里,等用完再删除

优点:支持大文件

缺点:效率比较低,需要写入临时文件

方法1:直接byte数组类型

@PostMapping(value = "/asyncImport")
public Boolean asyncImportForByteArray(@RequestParam("file") MultipartFile file) {

    try {
        // 获取字节数组:
        byte[] bytes = file.getBytes();
        
        //异步接口
        importService.asyncImportForByteArray(bytes);
        return true;
    } catch (IOException e) {
        throw new RuntimeException("出现错误");
    }
}



    @Async
    public String asyncImportForByteArray(byte[] bytes) {
        try {
            //**** 1.获取流
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            // 2.执行操作

            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        } finally {
        }
    }

方法2:临时文件方式

   /**
     * 上传的路径前缀
     */
    public static final String UPLOAD_PREFIX_PATH = "/opt/uploading";


    @PostMapping(value = "/asyncImport")
    public Boolean asyncImportForTempFile(@RequestParam("file") MultipartFile file) {
        try {
            // 生成临时文件
            File tempDirectory = new File(UPLOAD_PREFIX_PATH);
            if (!tempDirectory.exists()) {
                FileUtils.forceMkdir(tempDirectory);
            }
            File tempFile = new File(tempDirectory, file.getOriginalFilename());
            file.transferTo(tempFile);
            //异步接口
            importService.asyncImportForTempFile(tempFile);
            return true;
        } catch (IOException e) {
            throw new RuntimeException("出现错误");
        }
    }


     @Async
    public String asyncImportForTempFile(File tempFile) {
        try {
            // 1.获取流
            FileInputStream inputStream = FileUtils.openInputStream(tempFile);
            // 2.执行操作

            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        } finally {
          // chuan
            FileUtils.deleteQuietly(tempFile.getParentFile());
        }
    }

···
  <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>
  ····
  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值