多线程分片文件上传报FileNotFoundException异常
发布日期:2022-04-11 08:52:54 浏览次数:15 分类:技术文章

本文共 5752 字,大约阅读时间需要 19 分钟。

问题描述

出现java.io.IOException:java.io.FileNotFoundException:/home/admin/appName/.default/temp/tomcat.4504264197870423949.7001/work/Tomcat/Localhost/ROOT/upLoad_ff92855a_13c6_49d9_bbdf_1c062fb9bfd9_00000004.tmp(没有那个文件或目录)的错误。

错误部分代码:

// 写入分片的数据accessFile.write(bytes);//这里如果使用multipartFile.getBytes();则会出现FileNotFoundException异常。

这里如果使用multipartFile.getBytes();则会出现FileNotFoundException异常。

全部代码

package com.operative.core.d3DicomFile.controller;import com.aliyun.oss.model.PartETag;import com.aliyuncs.auth.sts.AssumeRoleResponse;import com.operative.base.annotation.OperationLogAnnotation;import com.operative.base.annotation.UnLogin;import com.operative.base.constants.SysLogConstants;import com.operative.base.http.ResponseData;import com.operative.base.http.ResponseStatus;import com.operative.base.http.Result;import com.operative.base.utils.OSSUtils;import com.operative.core.d3DicomFile.entity.D3DicomFile;import com.operative.core.d3DicomFile.service.D3DicomFileService;import com.operative.core.sysLog.entity.SysLog;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.scheduling.annotation.Async;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import java.io.*;import java.util.List;import java.util.Map;import java.util.UUID;import java.util.concurrent.*;import java.util.concurrent.atomic.AtomicInteger;/** * 

* 前端控制器 *

* * @author cst * @since 2021-09-06 */@CrossOrigin@RestController@RequestMapping("/d3DicomFile")public class D3DicomFileController {
@Autowired private D3DicomFileService d3DicomFileService; @Value("${path.static}") private String staticPath; private static final ConcurrentMap
TAP_BYTE = new ConcurrentHashMap<>(); // 文件MD5的缓存容器 private static final ConcurrentMap
MD5_CACHE = new ConcurrentHashMap<>(); private static final File tempFilePath = new File(""); static AtomicInteger c = new AtomicInteger(1); static ArrayBlockingQueue
queue = new ArrayBlockingQueue<>(2000); static ThreadPoolExecutor treadPool = new ThreadPoolExecutor( 6,//核心线程数 6,//最大线程数 0,//针对急救线程的生存时间,0的意思是没任务了直接释放 TimeUnit.MILLISECONDS,//针对急救线程的生存时间,0的意思是没任务了直接释放 queue,//工作队列,设置成了2,队列中最多两个线程排队 r -> new Thread(r,"myThread"+c.getAndIncrement()) ); /** * 大文件分片上传 * @param name 文件名 唯一不变 * @param md5 文件MD5值 * @param size 文件大小 总的大小 * @param chunks 总的分片数 * @param chunk 当前分片数 * @param multipartFile 分片流 * @throws IOException */// @PostMapping("/test") @PostMapping @UnLogin @Async public void chunkUpload1(String name, String md5, Long size, Integer chunks, Integer chunk, String fileName, @RequestParam("file") MultipartFile multipartFile) throws IOException {
final byte[] bytes = multipartFile.getBytes(); treadPool.submit(()->{
try {
chunkUpload(name, md5, size, chunks, chunk, fileName,bytes, multipartFile); } catch (IOException e) {
e.printStackTrace(); } }); } /** * 大文件分片上传 * @param name 文件名 唯一不变 * @param md5 文件MD5值 * @param size 文件大小 总的大小 * @param chunks 总的分片数 * @param chunk 当前分片数 * @param multipartFile 分片流 * @throws IOException */// @PostMapping("/test")// @PostMapping @UnLogin// @Async public void chunkUpload(String name, String md5, Long size, Integer chunks, Integer chunk, String fileName, byte[] bytes, @RequestParam("file") MultipartFile multipartFile) throws IOException {
File targetFile = MD5_CACHE.get(md5); //如果map中没有这个file文件路径 if (targetFile == null) {
// 没有生成的话就生成一个新的文件,没有做并发控制,多线程上传会出问题 targetFile = new File(System.getProperty("user.dir") + System.getProperty("file.separator") + staticPath + System.getProperty("file.separator"), name); //生成新文件 targetFile.getParentFile().mkdirs(); //放入map中进行标记,表示已经生成文件 MD5_CACHE.put(md5, targetFile); } System.out.println("targetFile"+targetFile); File newFile = new File(System.getProperty("user.dir") + System.getProperty("file.separator") + staticPath +System.getProperty("file.separator"), name); System.out.println("newFile"+newFile); // 可以对文件的任意位置进行读写 RandomAccessFile accessFile = new RandomAccessFile(newFile, "rw"); boolean finished = (chunk.equals(chunks));//是否最后一片 if (finished) {
//如果是最后一片 // 移动指针(光标)到指定位置 accessFile.seek(size - multipartFile.getSize()); }else {
accessFile.seek((chunk - 1) * multipartFile.getSize()); } // 写入分片的数据 accessFile.write(bytes);//这里如果使用multipartFile.getBytes();则会出现FileNotFoundException异常。 accessFile.close(); if (finished) {
System.out.println("success."); // 上传成功 MD5_CACHE.remove(md5); } }}

同一个文件上传时间对比

直接上传

在这里插入图片描述

分片上传

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


可用线程池对线程进行管理

转载地址:https://blog.csdn.net/LJWWD/article/details/123561561 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:多线程分页查询
下一篇:多线程函数指针

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月05日 19时37分42秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章