• spring boot 大文件上传实现方式(一)


    控制器
    /**
    * 上传文件
    *
    * @param param
    * @param request
    * @return
    * @throws Exception
    */
    @ApiOperation(value = "大文件上传")
    @PostMapping(value = "/fileUpload")
    @ResponseBody
    public Result<String> fileUpload(MultipartFileParam param, HttpServletRequest request) {
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    String parentId = request.getParameter("parentId");
    if (isMultipart) {
    logger.info("上传文件start。");
    try {
    personKnowledgeService.uploadFileByMappedByteBuffer(param,parentId);
    } catch (IOException e) {
    e.printStackTrace();
    logger.error("文件上传失败。{}", param.toString());
    return JsonError("上传失败");
    }
    logger.info("上传文件end。");
    }
    return JsonSuccess("上传成功");
    }



    实现方法


    /**
    * 上传文件方法2
    * 处理文件分块,基于MappedByteBuffer来实现文件的保存
    *
    * @param param
    * @throws IOException
    */
    @Override
    public void uploadFileByMappedByteBuffer(MultipartFileParam param, String parentId) throws IOException {

    String basePath = System.getProperty("user.dir") + File.separator;
    Date now = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    String nowDayStr = sdf.format(now);
    String filePath = "knowledge" + File.separator + "upload" + File.separator + nowDayStr + File.separator;

    String fileName = param.getName();
    String uploadDirPath = basePath + filePath + param.getUid();
    String tempFileName = fileName + "_tmp";
    File tmpDir = new File(uploadDirPath);
    File tmpFile = new File(uploadDirPath, tempFileName);
    if (!tmpDir.exists()) {
    tmpDir.mkdirs();
    }

    //添加记录
    long CHUNK_SIZE = 5242880;//5M
    String uid = param.getUid();
    PersonKnowledge model = personKnowledgeRepository.findFirstByFileuid(uid);
    if (model == null) {
    model = new PersonKnowledge();
    model.setCreateTime(new Date());
    model.setCreateId(SecurityUtils.getSubject().getCurrentUser().getId());
    if (StringUtils.isEmpty(parentId)) {
    parentId = "ROOT";
    }
    model.setParentId(parentId);
    model.setAttchmentType(PersonKnowledgeType.文件.getId());
    String suffixName = fileName.substring(fileName.lastIndexOf("."));
    model.setName(fileName.substring(0, fileName.lastIndexOf("."))); // 新文件名
    model.setAttachmentPath(uploadDirPath + File.separator + fileName); //文件路径
    model.setSuffix(suffixName.toLowerCase().substring(1));
    model.setFileuid(uid);
    //获取文件大小
    Long size = CHUNK_SIZE * param.getChunks();
    String fileSizeString = "";
    DecimalFormat df = new DecimalFormat("#.00");
    if (size != null) {
    if (size < 1024) {
    fileSizeString = df.format((double) size) + "B";
    model.setFileSize(fileSizeString);
    } else if (size < 1048576) {
    fileSizeString = df.format((double) size / 1024) + "K";
    model.setFileSize(fileSizeString);
    } else if (size < 1073741824) {
    fileSizeString = df.format((double) size / 1048576) + "M";
    model.setFileSize(fileSizeString);
    } else {
    fileSizeString = df.format((double) size / 1073741824) + "G";
    model.setFileSize(fileSizeString);
    }
    }
    personKnowledgeRepository.save(model);
    }

    RandomAccessFile tempRaf = new RandomAccessFile(tmpFile, "rw");
    FileChannel fileChannel = tempRaf.getChannel();

    //写入该分片数据

    long offset = CHUNK_SIZE * param.getChunk();
    byte[] fileData = param.getFile().getBytes();
    MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, offset, fileData.length);
    mappedByteBuffer.put(fileData);
    // 释放
    FileMD5Util.freedMappedByteBuffer(mappedByteBuffer);
    fileChannel.close();

    boolean isOk = checkAndSetUploadProgress(param, uploadDirPath);
    if (isOk) {
    boolean flag = renameFile(tmpFile, fileName);
    System.out.println("upload complete !!" + flag + " name=" + fileName);
    }
    }

    /**
    * 检查并修改文件上传进度
    *
    * @param param
    * @param uploadDirPath
    * @return
    * @throws IOException
    */
    private boolean checkAndSetUploadProgress(MultipartFileParam param, String uploadDirPath) throws IOException {
    String fileName = param.getName();
    File confFile = new File(uploadDirPath, fileName + ".conf");
    RandomAccessFile accessConfFile = new RandomAccessFile(confFile, "rw");
    //把该分段标记为 true 表示完成
    System.out.println("set part " + param.getChunk() + " complete");
    accessConfFile.setLength(param.getChunks());
    accessConfFile.seek(param.getChunk());
    accessConfFile.write(Byte.MAX_VALUE);

    //completeList 检查是否全部完成,如果数组里是否全部都是(全部分片都成功上传)
    byte[] completeList = FileUtils.readFileToByteArray(confFile);
    byte isComplete = Byte.MAX_VALUE;
    for (int i = 0; i < completeList.length && isComplete == Byte.MAX_VALUE; i++) {
    //与运算, 如果有部分没有完成则 isComplete 不是 Byte.MAX_VALUE
    isComplete = (byte) (isComplete & completeList[i]);
    System.out.println("check part " + i + " complete?:" + completeList[i]);
    }

    accessConfFile.close();
    if (isComplete == Byte.MAX_VALUE) {
    //stringRedisTemplate.opsForHash().put(Constants.FILE_UPLOAD_STATUS, param.getMd5(), "true");
    //stringRedisTemplate.opsForValue().set(Constants.FILE_MD5_KEY + param.getMd5(), uploadDirPath + "/" + fileName);
    return true;
    } else {
    // if (!stringRedisTemplate.opsForHash().hasKey(Constants.FILE_UPLOAD_STATUS, param.getMd5())) {
    // stringRedisTemplate.opsForHash().put(Constants.FILE_UPLOAD_STATUS, param.getMd5(), "false");
    // }
    // if (stringRedisTemplate.hasKey(Constants.FILE_MD5_KEY + param.getMd5())) {
    // stringRedisTemplate.opsForValue().set(Constants.FILE_MD5_KEY + param.getMd5(), uploadDirPath + "/" + fileName + ".conf");
    // }
    return false;
    }
    }

    /**
    * 文件重命名
    *
    * @param toBeRenamed 将要修改名字的文件
    * @param toFileNewName 新的名字
    * @return
    */
    public boolean renameFile(File toBeRenamed, String toFileNewName) {
    //检查要重命名的文件是否存在,是否是文件
    if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {
    //logger.info("File does not exist: " + toBeRenamed.getName());
    return false;
    }
    String p = toBeRenamed.getParent();
    File newFile = new File(p + File.separatorChar + toFileNewName);
    //修改文件名
    return toBeRenamed.renameTo(newFile);
    }


    实体Model
    public class MultipartFileParam {
    // uid
    private String uid;

    //总分片数量
    private int chunks;
    //当前为第几块分片
    private int chunk;

    //文件名
    private String name;
    //分片对象
    private MultipartFile file;
    // MD5
    private String md5;

    public String getUid() {
    return uid;
    }

    public void setUid(String uid) {
    this.uid = uid;
    }

    public int getChunks() {
    return chunks;
    }

    public void setChunks(int chunks) {
    this.chunks = chunks;
    }

    public int getChunk() {
    return chunk;
    }

    public void setChunk(int chunk) {
    this.chunk = chunk;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public MultipartFile getFile() {
    return file;
    }

    public void setFile(MultipartFile file) {
    this.file = file;
    }

    public String getMd5() {
    return md5;
    }

    public void setMd5(String md5) {
    this.md5 = md5;
    }

    }
  • 相关阅读:
    hdu acm 2844 Coins 解题报告
    hdu 1963 Investment 解题报告
    codeforces 454B. Little Pony and Sort by Shift 解题报告
    广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
    hdu acm 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    hdu acm 1114 Piggy-Bank 解题报告
    poj 2531 Network Saboteur 解题报告
    数据库范式
    ngnix 配置CI框架 与 CI的简单使用
    Vundle的安装
  • 原文地址:https://www.cnblogs.com/gaozs/p/11514211.html
Copyright © 2020-2023  润新知