java实现大文件分片上传

本文介绍了如何使用Java优化大文件上传功能,通过前端webUploader分片文件,后端按顺序接收并直接合并存储,避免了之前一次性接收整个大文件导致的速度问题。
摘要由CSDN通过智能技术生成

java实现大文件分片上传

在项目中用到了大文件上传功能,最初从网上参考了一些代码来实现,但是最终的上传效果不是很好,速度比较慢。

之前的上传思路是:

  1. 前端利用webUploader分片大文件
  2. 后端接收各个分片后的小文件
  3. 接收完一个大文件的所有分片文件后,合并这些文件为大文件

现在的思路是:

  1. 前端利用webUploader分片大文件

  2. 后端接收各个分片后的小文件

  3. 将接收到的小文件直接存到目标文件夹

  4. 需要注意的是,一定要按分片顺序来存储小文件,不然最后生成的

    文件和原文件不一样,会被损坏

代码实现:

后端:

MediaUploadInfoController.java

/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.uploadfiles.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.thinkgem.jeesite.common.response.Code;
import com.thinkgem.jeesite.common.response.Result;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.modules.mediafileinfo.entity.MediaFileInfo;
import com.thinkgem.jeesite.modules.mediafileinfo.service.MediaFileInfoService;
import com.thinkgem.jeesite.modules.sys.entity.Company;
import com.thinkgem.jeesite.modules.sys.entity.MediaType;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.MediaSysCompanyService;
import com.thinkgem.jeesite.modules.sys.service.TypeService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.uploadfiles.entity.MediaUploadInfo;
import com.thinkgem.jeesite.modules.uploadfiles.service.MediaUploadInfoService;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 上传文件信息Controller
 * @author admin
 * @version 2018-07-11
 */
@Controller
@RequestMapping(value = "${adminPath}/uploadfiles/mediaUploadInfo")
public class MediaUploadInfoController extends BaseController {
   

   @Autowired
   private MediaUploadInfoService mediaUploadInfoService;
   @Autowired
   private MediaSysCompanyService mediaSysCompanyService;
   @Autowired
   private TypeService typeService;
   @Autowired
   private MediaFileInfoService mediaFileInfoService;
   
   @ModelAttribute
   public MediaUploadInfo get(@RequestParam(required=false) String id) {
   
      MediaUploadInfo entity = null;
      if (StringUtils.isNotBlank(id) && !StringUtils.contains(id, "WU_FILE")){
   
         entity = mediaUploadInfoService.get(id);
      }
      if (entity == null){
   
         entity = new MediaUploadInfo();
      }
      return entity;
   }
   
// @RequiresPermissions("uploadfiles:mediaUploadInfo:view")
   @RequestMapping(value = {
   "list", ""})
   public String list(MediaUploadInfo mediaUploadInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
   
      //todo 获得用户
      User user = UserUtils.getUser();
      mediaUploadInfo.setCreateBy(user);
      Page<MediaUploadInfo> page = mediaUploadInfoService.findPage(new Page<MediaUploadInfo>(request, response), mediaUploadInfo);
      model.addAttribute("page", page);
      return "modules/uploadfiles/mediaUploadInfoList";
   }

// @RequiresPermissions("uploadfiles:mediaUploadInfo:view")
   @RequestMapping(value = "form")
   public String form(MediaUploadInfo mediaUploadInfo, Model model, @RequestParam(required = false) String rootId) {
   
      User user = UserUtils.getUser();
      String companyId = user.getCompany().getId();
      Company company = mediaSysCompanyService.get(Integer.valueOf(companyId));
      List<MediaType> typeList = typeService.getLastLevelTypes(rootId);
      model.addAttribute("UUID", IdGen.uuid());
      model.addAttribute("typeList", typeList);
      model.addAttribute("company", company);
      model.addAttribute("mediaUploadInfo", mediaUploadInfo);
      if ("1".equals(rootId))
         return "modules/uploadfiles/mediaUploadInfoForm";
      else
         return "modules/uploadfiles/vedioUploadInfoForm";
   }

   @RequiresPermissions("uploadfiles:mediaUploadInfo:edit")
   @RequestMapping(value = "save")
   public String save(MediaUploadInfo mediaUploadInfo, Model model, RedirectAttributes redirectAttributes) {
   
      if (!beanValidator(model, mediaUploadInfo)){
   
         return form(mediaUploadInfo, model, null);
      }
      mediaUploadInfoService.save(mediaUploadInfo);
      addMessage(redirectAttributes, "保存文件成功");
      return "redirect:"+Global.getAdminPath()+"/uploadfiles/mediaUploadInfo/?repage";
   }
   
   @RequiresPermissions("uploadfiles:mediaUploadInfo:edit")
   @RequestMapping(value = "delete")
   public String delete(MediaUploadInfo mediaUploadInfo, RedirectAttributes redirectAttributes) {
   
      mediaUploadInfoService.delete(mediaUploadInfo);
      addMessage(redirectAttributes, "删除文件成功");
      return "redirect:"+Global.getAdminPath()+"/uploadfiles/mediaUploadInfo/?repage";
   }


   /**
    * 分片上传文件
    *
    * @param mediaUploadInfo MediaUploadInfo实体
    * @param mediaFileInfo MediaFileInfo实体
    * @param uploadCounts 上传的文件总数量
    * @param UUID 作为media_upload_info表中数据主键
    * @param isCover 是否是封面,图片上传时用于判定封面图片
    * @param isVideo 是否是视频文件
    * @param chunks 文件总的分片数量
    * @param chunk 当前分片
    * @param name 名字
    * @param request 请求
    * @param file 文件
    * @param md5Value 文件MD5值,用于多文件上传时,判定是不是相同文件
    * @return json信息
    */
   @RequestMapping("/sliceUploadFiles")
   @ResponseBody
   public Map<String, Object> sliceUploadFiles(MediaUploadInfo mediaUploadInfo,
                                    MediaFileInfo mediaFileInfo,
                                    int uploadCounts,
                                    String UUID,
                                    Boolean isCover,
                                    Boolean isVideo,
                                    String chunks,
                                    String chunk,
                                    String name,
                                    HttpServletRequest request,
                                    MultipartFile file,
                                    String md5Value) {
   
      try {
   
         return mediaUploadInfoService.sliceUploadFiles(mediaUploadInfo, mediaFileInfo, uploadCounts, UUID, isCover, isVideo, chunks, chunk, name, request, file, md5Value);
      } catch (Exception e) {
   
         return Result.Error(Code.SYSTEM_ERROR);
      }
   }

   /**
    * 视频上传封面上传
    *
    * @param cover
    * @param UUID
    * @param mediaUploadInfo
    * @return
    */
   @RequestMapping("/coverUpload")
   @ResponseBody
   public Map<String, Object> coverUpload(HttpServletRequest request, MultipartFile file, String UUID, MediaUploadInfo mediaUploadInfo, String md5Value) {
   
      return mediaUploadInfoService.coverUpload(request, file, UUID, mediaUploadInfo, md5Value);
   }

   /**
    * 批量删除文件
    *
    * @param ids 多个文件ID,用“,”隔开
    * @return
    */
   @RequestMapping("/batchDelete")
   @ResponseBody
   @Transactional
   public Map<String, Object> batchDelete(String ids){
   
      String[] strings = ids != null ? ids.split(",") : null;
      if (strings != null && strings.length > 0){
   
         List<String> pkIds = Arrays.asList(strings);
         //批量删除可以被删除的文件信息,审核通过的不能删除
         Integer count = mediaUploadInfoService.batchDelete(pkIds);
         Integer count1 = mediaFileInfoService.batchDelete(pkIds);
         if (count == 0 && count1 == 0){
   
            return Result.Success("您选择的文件因为已经审核通过,不能删除!");
         }else {
   
            return Result.Success("您选择的文件删除成功!");
         }
      }else {
   
         return Result.Error(Code.PARAM_ERROR);
      }
   }

}

MediaUploadInfoService.java

/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.uploadfiles.service;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.response.Code;
import com.thinkgem.jeesite.common.response.Result;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.FileUtils;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.common.utils.UploadFiles.OperatingFileUtil;
import com.thinkgem.jeesite.modules.mediafileinfo.entity.MediaFileInfo;
import com.thinkgem.jeesite.modules.mediafileinfo.service.MediaFileInfoService;
import com.thinkgem.jeesite.modules.sys.entity.MediaType;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.TypeService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import com.thinkgem.jeesite.modules.uploadfiles.dao.MediaUploadInfoDao;
import com.thinkgem.jeesite.modules.uploadfiles.entity.MediaUploadInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.<
  • 2
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值