JAVA大文件上传分片上传方法(附带demo)

  最近在做视频上传展示的相关业务!但是因为最开始使用的是单文件上传所以一旦遇到大文件上传的速度就非常慢!为此在网上一直找寻分片的方法!得到了思路!

直接讲一下我这边看了那么多文档加上自己理解写的demo(虽然前端大部分代码是网上的)!
在看demo之前需要理解这个分片的思路。

1、假设现在有一个很大的石头搬到某个地方你直接搬的话那么就是走的非常慢还有可能因为外部因素搬到一般摔了那就做了无用功了。
那么现在把石头切割成多个小块你搬小部分石头是不是就很快,然后当全部小石头搬完后在目的地把这些小石头拼接起来是不是还是原来的样
子(别抬杠)。
2、那么分片的原理就是这样文件太大切割成多个小文件在后台接收这些分片然后创建临时文件。在所有分片传完之后调用后台合并接口,将
刚才的分片合并成完整的文件。

直接上前端代码:




    
    JS分片上传-极速上传




后台代码:

 private static String fileUploadTempDir = "D:/portalupload/fileuploaddir";
    private static String fileUploadDir = "D:/portalupload/file";
   @RequestMapping("/doPost")
    @ResponseBody
    public Map fragmentation(HttpServletRequest req, HttpServletResponse resp) {
        resp.addHeader("Access-Control-Allow-Origin", "*");
        Map map = new HashMap<>();

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;

        // 获得文件分片数据
        MultipartFile file = multipartRequest.getFile("data");
//        分片第几片
        int index = Integer.parseInt(multipartRequest.getParameter("index"));
//        总片数
        int total = Integer.parseInt(multipartRequest.getParameter("total"));
//        获取文件名
        String fileName = multipartRequest.getParameter("name");
        String name = fileName.substring(0, fileName.lastIndexOf("."));
        String fileEnd = fileName.substring(fileName.lastIndexOf("."));
//        前端uuid,作为标识
        String uuid = multipartRequest.getParameter("uuid");

        File uploadFile = new File(fileUploadTempDir + "/" + uuid, uuid + name + index + ".tem");

        if (!uploadFile.getParentFile().exists()) {
            uploadFile.getParentFile().mkdirs();
        }

        if (index < total) {
            try {
                file.transferTo(uploadFile);
                // 上传的文件分片名称
                map.put("status", 201);
                return map;
            } catch (IOException e) {
                e.printStackTrace();
                map.put("status", 502);
                return map;
            }
        } else {
            try {
                file.transferTo(uploadFile);
                // 上传的文件分片名称
                map.put("status", 200);
                return map;
            } catch (IOException e) {
                e.printStackTrace();
                map.put("status", 502);
                return map;
            }
        }
    }
   @RequestMapping(value = "/merge", method = RequestMethod.GET)
    @ResponseBody
    public Map merge(String uuid, String newFileName) {
        Map retMap = new HashMap();
        try {
            File dirFile = new File(fileUploadTempDir + "/" + uuid);
            if (!dirFile.exists()) {
                throw new RuntimeException("文件不存在!");
            }
            //分片上传的文件已经位于同一个文件夹下,方便寻找和遍历(当文件数大于十的时候记得排序用冒泡排序确保顺序是正确的)
            String[] fileNames = dirFile.list();

//       创建空的合并文件
            File targetFile = new File(fileUploadDir, newFileName);
            RandomAccessFile writeFile = new RandomAccessFile(targetFile, "rw");

            int position = 0;
            for (String fileName : fileNames) {
                System.out.println(fileName);
                File sourceFile = new File(fileUploadTempDir + "/" + uuid, fileName);
                RandomAccessFile readFile = new RandomAccessFile(sourceFile, "rw");
                int chunksize = 1024 * 3;
                byte[] buf = new byte[chunksize];
                writeFile.seek(position);
                int byteCount = 0;
                while ((byteCount = readFile.read(buf)) != -1) {
                    if (byteCount != chunksize) {
                        byte[] tempBytes = new byte[byteCount];
                        System.arraycopy(buf, 0, tempBytes, 0, byteCount);
                        buf = tempBytes;
                    }
                    writeFile.write(buf);
                    position = position + byteCount;
                }
                readFile.close();
                FileUtils.deleteQuietly(sourceFile);//删除缓存的临时文件
            }
            writeFile.close();
            retMap.put("code", "200");
        }catch (IOException e){
            e.printStackTrace();
            retMap.put("code", "500");
        }
        return retMap;
    }

大概就是这样的思路。
如有更好的方法请告诉小弟,小弟也在学习中。

你可能感兴趣的:(java前端)