大文件分片上传

前言

前端进行文件大小分割  ,按10M分割进行分片上传,使用的项目还是前面文档介绍的poi同一个项目

另一篇poi导出文章,使用的同一个项目

poi的使用和工具类(一)

 开发

1、maven依赖

<!--文件分片上传使用到依赖 start  -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>16.0.1</version>
</dependency>
<dependency>
    <groupId>com.twmacinta</groupId>
    <artifactId>fast-md5</artifactId>
    <version>2.7.1</version>
</dependency>

<!--文件分片上传使用到依赖 end  -->

配置文件

server:
  port: 9001

#  rootdir文件上传根路径  linux:/xxx/xx/ window D:\Download\
#  tempdir: 分片临时目录
#  isDelTempFile   和片后是否删除临时目录
spring:
  uploader:
    rootdir: D:\Download\
    tempdir: temp
    isDelTempFile: true

 controller

package com.shan.controller;

import com.shan.service.UploaderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 分片上传
 * 思想
 * 1. 先 checkUpload()  文件上传前校验 根据自己公司需求校验
 *2. checkChunk()  检测指定分片是否存在   否 走uploadChunk()分片上传方法  是走merge()合成分片
 * 3. 分片上传时,会生成临时文件  必成分片是会把临时文件合成上传的真正文件,并删除临时文件
 *
 */
@RestController
@RequestMapping("uploader")
public class TestUploader {


    @Autowired
    private UploaderService uploaderService;

    /**
     * 文件上传前校验
     *
     * @param fileName 文件名称
     * @param size     文件大小 byte字节长度
     * @return
     */
    @PostMapping("/checkUpload")
    public String checkUpload(String fileName, String size) {
        //根据公司自己业务  做校验   如文件名是否喊特殊字符 是否为空 等
        return "SUCCESS";
    }


    /**
     * 检查指定分片是否存在
     *
     * @param md5Value    文件MD5值
     * @param chunk       第几片
     * @param moduleName  上传文件所在模块名称
     * @param fileTypeKey 文件类别   公司自己业务需求  会根据 模块名称+文件类别  定义上传目录
     * @return
     */
    @PostMapping("/checkChunk")
    public Boolean checkChunk(String md5Value, Integer chunk, String moduleName, String fileTypeKey) {
        Boolean bool = uploaderService.checkChunk(md5Value, chunk, moduleName, fileTypeKey);
        return bool;
    }


    /**
     * 分片上传
     *
     * @param file        文件对象
     * @param md5Value    文件MD5值
     * @param chunk       第几片
     * @param moduleName  上传文件所在模块名称
     * @param fileTypeKey 文件类别
     * @return
     */
    @PostMapping("/uploadChunk")
    public String uploadChunk(MultipartFile file, String md5Value, Integer chunk, String moduleName, String fileTypeKey) {
        System.out.println("------------开始上传:" + file.getOriginalFilename());
        Boolean bool = uploaderService.uploadChunk(file, md5Value, chunk, moduleName, fileTypeKey);
        if (!bool) {
            return "FAILRE";
        }
        return "SUCCESS";
    }


    /**
     * 合成分片
     *
     * @param chunkCount  总片数
     * @param md5Value    文件MD5值
     * @param fileName    文件名称
     * @param moduleName  上传文件所在模块名称
     * @param fileTypeKey 文件类别
     * @return
     */
    @PostMapping("/merge")
    public String merge(Integer chunkCount, String md5Value, String fileName, String moduleName, String fileTypeKey) {
        String fileId = uploaderService.merge(chunkCount, md5Value, fileName, moduleName, fileTypeKey);
        if (StringUtils.isBlank(fileId)) {
            return "FAILRE";
        }
        return "SUCCESS";
    }

}

service

package com.shan.service;

import org.springframework.web.multipart.MultipartFile;

public interface UploaderService {


    Boolean checkChunk(String md5Value, Integer chunk, String moduleName, String fileTypeKey);

    Boolean uploadChunk(MultipartFile file, String md5Value, Integer chunk, String moduleName, String fileTypeKey);

    String merge(Integer chunkCount, String md5Value, String fileName, String moduleName, String fileTypeKey);

    String specifiedDirectory(String fileTypeKey);

}
package com.shan.service.impl;

import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.shan.entity.po.CloudFile;
import com.shan.file.ResumeUploader;
import com.shan.service.UploaderService;
import com.shan.utils.ConstantUtils;
import com.shan.utils.Md5Util;
import com.shan.utils.UUIDGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Date;
import java.util.Map;

@Service
public class UploaderServiceImpl implements UploaderService {

    @Value("${spring.uploader.rootdir}")
    private String fileUploadPath;

    @Autowired
    private  ResumeUploader fileOperation;


    @Override
    public Boolean checkChunk(String md5Value, Integer chunk, String moduleName, String fileTypeKey) {
        String path = specifiedDirectory(fileTypeKey) + moduleName + File.separator + fileTypeKey + File.separator;
        return fileOperation.checkChunk(path, md5Value, chunk);
    }

    @Override
    public Boolean uploadChunk(MultipartFile file, String md5Value, Integer chunk, String moduleName, String fileTypeKey) {
        String path = specifiedDirectory(fileTypeKey) + moduleName + File.separator + fileTypeKey + File.separator;
        return fileOperation.upload(file, path, md5Value, chunk);
    }

    @Override

    public String merge(Integer chunkCount, String md5Value, String fileName, String moduleName, String fileTypeKey) {
        String path = specifiedDirectory(fileTypeKey) + moduleName + File.separator + fileTypeKey + File.separator;

        // 目录下如果存在相同名称的文件,对文件名称做修改   xxx(1).txt  xxx(2).txt
        fileName = this.verifyRepeatFile(path, fileName, 0);
        Boolean merge = fileOperation.merge(path, path, md5Value, chunkCount, fileName);
        if (merge) {
            String filePath = path + fileName;
            CloudFile cloudFile = new CloudFile();
            cloudFile.setId(UUIDGenerator.getUUID());
            cloudFile.setMd5(Md5Util.fastMD5(new File(filePath)));
            cloudFile.setName(fileName.substring(0, fileName.lastIndexOf(".")));
            cloudFile.setType(fileName.substring(fileName.lastIndexOf(".")));
            cloudFile.setPath(filePath);
            cloudFile.setFileSize(new File(filePath).length());
            cloudFile.setGmtCreate(new Date());
            //存数据库
           // int save = cloudFileMapper.save(cloudFile);
            int save =1;
            if (save > 0) {
                return cloudFile.getId();
            }
        }
        return null;
    }

    /**
     * 根据文件类型指定文件目录
     *
     * @param fileTypeKey 文件类型
     */
    @Override
    public String specifiedDirectory(String fileTypeKey) {
        // 一、通用管理文件根路径
        String fPath = fileUploadPath;
        return fPath.endsWith("/") ? fPath : fPath + "/";
    }



    private String verifyRepeatFile(String path, String fileName, int i) {
        String name = fileName.substring(0, fileName.lastIndexOf("."));
        String suffix = fileName.substring(fileName.lastIndexOf("."));

        String tempFileName;
        if (i != 0) {
            tempFileName = String.format("%s%s%d%s", name, "(", i, ")");
        } else {
            tempFileName = name;
        }
        File file = new File(path + tempFileName + suffix);
        if (file.exists()) {
            return verifyRepeatFile(path, name + suffix, ++i);
        }
        return tempFileName + suffix;
    }

}

 工具类 上传相关封装

ResumeUploader、CommonUploader、UploaderUtils 、UploaderUtils
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.shan.file;

import java.io.InputStream;
import java.util.List;

import com.shan.entity.bean.FileInfo;
import org.springframework.web.multipart.MultipartFile;

public interface ResumeUploader {
    Boolean checkChunk(String var1, String var2, Integer var3);

    Boolean compress(List<String> var1, String var2);

    Boolean copy(String var1, String var2);

    Boolean delete(String var1);

    InputStream download(String var1);

    Boolean exists(String var1);

    Long getDiskSize(String var1);

    List<FileInfo> listFiles(String var1, boolean var2);

    Boolean merge(String var1, String var2, String var3, Integer var4, String var5);

    Boolean mkDir(String var1);

    Boolean move(String var1, String var2);

    Boolean rename(String var1, String var2);

    Boolean upload(MultipartFile var1, String var2, String var3, Integer var4);
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.shan.file;

import com.google.common.collect.Lists;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.shan.entity.bean.FileInfo;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@Component
public class CommonUploader implements ResumeUploader {
    @Value("${spring.uploader.tempdir}")
    private String tempDir;
    @Value("${spring.uploader.isDelTempFile}")
    private Boolean isDelTempFile;

    public Boolean checkChunk(String sharePath, String md5File, Integer chunk) {
        Boolean isExisted = false;
        String filePath = String.format("%s/%s/%s/%s.tmp", sharePath, this.tempDir, md5File, chunk);
        File file = new File(filePath);
        if (file.exists()) {
            isExisted = true;
        }

        return isExisted;
    }

    public Boolean compress(List<String> inputFilename, String zipFilename) {
        Boolean result = false;

        try {
            this.mkDir(zipFilename.substring(0, zipFilename.lastIndexOf("/") + 1));
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilename));

            try {
                String item;
                String base;
                for(Iterator var5 = inputFilename.iterator(); var5.hasNext(); this.zip(out, item, base)) {
                    item = (String)var5.next();
                    base = "";
                    String[] items = item.split("/");
                    if (item.lastIndexOf("/") + 1 == item.length()) {
                        base = items[items.length - 1] + "/";
                    } else {
                        base = items[items.length - 1];
                    }
                }

                result = true;
            } catch (Throwable var10) {
                try {
                    out.close();
                } catch (Throwable var9) {
                    var10.addSuppressed(var9);
                }

                throw var10;
            }

            out.close();
        } catch (Exception var11) {
            var11.printStackTrace();
            result = false;
        }

        return result;
    }

    public Boolean copy(String fromPath, String tofilePath) {
        Boolean result = false;

        try {
            File fromFile = new File(fromPath);
            File toFile = new File(tofilePath);
            if (fromFile.exists()) {
                if (fromFile.isDirectory()) {
                    FileUtils.copyDirectory(fromFile, toFile);
                } else {
                    FileUtils.copyFile(fromFile, toFile);
                }

                result = toFile.exists();
            }
        } catch (Exception var6) {
            var6.printStackTrace();
            result = false;
        }

        return result;
    }

    public Boolean delete(String path) {
        Boolean result = false;

        try {
            File remoteFile = new File(path);
            if (!remoteFile.exists()) {
                return false;
            }

            if (remoteFile.isFile()) {
                result = remoteFile.delete();
            } else {
                FileUtils.deleteDirectory(remoteFile);
                result = true;
            }
        } catch (Exception var4) {
            var4.printStackTrace();
            result = false;
        }

        return result;
    }

    public InputStream download(String fromPath) {
        FileInputStream inputStream = null;

        try {
            File file = new File(fromPath);
            if (file.exists()) {
                inputStream = new FileInputStream(file);
            }
        } catch (Exception var4) {
            var4.printStackTrace();
        }

        return inputStream;
    }

    public Boolean exists(String path) {
        return (new File(path)).exists();
    }

    public Long getDiskSize(String path) {
        return this.getDiskSizeByte(path) / 1024L;
    }

    private Long getDiskSizeByte(String path) {
        long result = 0L;

        try {
            File file = new File(path);
            if (file.isFile()) {
                result += file.length();
            } else {
                File[] files = file.listFiles();
                File[] var6 = files;
                int var7 = files.length;

                for(int var8 = 0; var8 < var7; ++var8) {
                    File f = var6[var8];
                    if (f.isFile()) {
                        result += f.length();
                    }

                    if (f.isDirectory()) {
                        result += this.getDiskSizeByte(f.getPath().substring(f.getPath().indexOf("@") + 1));
                    }
                }
            }
        } catch (Exception var10) {
            var10.printStackTrace();
            return 0L;
        }

        return result;
    }

    public List<FileInfo> listFiles(String path, boolean calculateFolderSize) {
        ArrayList result = Lists.newArrayList();

        try {
            File file = new File(path);
            if (file.exists() && file.isDirectory()) {
                File[] files = file.listFiles();
                File[] var6 = files;
                int var7 = files.length;

                for(int var8 = 0; var8 < var7; ++var8) {
                    File f = var6[var8];
                    Boolean isFile = f.isFile();
                    String filePath = f.getPath();
                    String fileName = isFile ? f.getName() : "";
                    Long size = 0L;
                    if (isFile) {
                        size = f.length() / 1024L;
                    } else if (calculateFolderSize) {
                        size = this.getDiskSize(filePath.substring(filePath.indexOf("@") + 1));
                    }

                    result.add(new FileInfo(f.getName(), isFile, f.getPath(), fileName.substring(fileName.lastIndexOf(".") + 1), size));
                }
            }
        } catch (Exception var14) {
            var14.printStackTrace();
        }

        return result;
    }

    public Boolean merge(String uploadPath, String temPath, String md5File, Integer chunks, String name) {
        Boolean result = false;
        this.mkDir(uploadPath);
        this.mkDir(temPath);

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(String.format("%s/%s", uploadPath, name));

            try {
                byte[] buf = new byte[104857600];
                long i = 0L;

                while(true) {
                    if (i >= (long)chunks) {
                        if (this.isDelTempFile) {
                            this.delete(String.format("%s/%s/%s/", temPath, this.tempDir, md5File));
                        }

                        result = true;
                        break;
                    }

                    File file = new File(String.format("%s/%s/%s/%s.tmp", temPath, this.tempDir, md5File, i));
                    FileInputStream inputStream = new FileInputStream(file);

                    try {
                        boolean var13 = false;

                        int len;
                        while((len = inputStream.read(buf)) != -1) {
                            fileOutputStream.write(buf, 0, len);
                        }
                    } catch (Throwable var17) {
                        try {
                            inputStream.close();
                        } catch (Throwable var16) {
                            var17.addSuppressed(var16);
                        }

                        throw var17;
                    }

                    inputStream.close();
                    ++i;
                }
            } catch (Throwable var18) {
                try {
                    fileOutputStream.close();
                } catch (Throwable var15) {
                    var18.addSuppressed(var15);
                }

                throw var18;
            }

            fileOutputStream.close();
        } catch (Exception var19) {
            result = false;
        }

        return result;
    }

    public Boolean mkDir(String path) {
        Boolean result = false;

        try {
            File file = new File(path);
            if (!file.exists()) {
                result = file.mkdirs();
            }
        } catch (Exception var4) {
            var4.printStackTrace();
            result = false;
        }

        return result;
    }

    public Boolean move(String fromPath, String toPath) {
        Boolean result = false;

        try {
            Boolean isCopy = this.copy(fromPath, toPath);
            Boolean isDel = false;
            if (isCopy) {
                isDel = this.delete(fromPath);
            }

            result = isCopy && isDel;
        } catch (Exception var6) {
            var6.printStackTrace();
            result = false;
        }

        return result;
    }

    public Boolean rename(String oldName, String newName) {
        Boolean result = false;

        try {
            File oldFile = new File(oldName);
            File newFile = new File(newName);
            oldFile.renameTo(newFile);
            result = newFile.exists();
        } catch (Exception var6) {
            var6.printStackTrace();
            result = false;
        }

        return result;
    }

    public Boolean upload(MultipartFile file, String sharePath, String md5File, Integer chunk) {
        try {
            String path = String.format("%s/%s/%s/", sharePath, this.tempDir, md5File);
            FileUtils.forceMkdir(new File(path));
            String chunkName = chunk == null ? "0.tmp" : chunk.toString().concat(".tmp");
            File savefile = new File(path.concat(chunkName));
            if (!savefile.exists()) {
                savefile.createNewFile();
            }

            file.transferTo(savefile);
        } catch (IOException var8) {
            return false;
        }

        return true;
    }

    private void zip(ZipOutputStream out, String inputFilename, String base) throws Exception {
        File file = new File(inputFilename);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                base = base.length() == 0 ? "" : base;

                for(int i = 0; i < files.length; ++i) {
                    String filePath = files[i].getPath();
                    this.zip(out, filePath.substring(filePath.indexOf("@") + 1), base + files[i].getName());
                }
            } else {
                out.putNextEntry(new ZipEntry(base));
                int len = 0;
                byte[] buf = new byte[104857600];
                FileInputStream inputStream = new FileInputStream(file);
                try {
                    while((len = inputStream.read(buf)) != -1) {
                        out.write(buf, 0, len);
                    }
                } catch (Throwable var11) {
                    try {
                        inputStream.close();
                    } catch (Throwable var10) {
                        var11.addSuppressed(var10);
                    }

                    throw var11;
                }

                inputStream.close();
            }
        }

    }

    public String getTempDir() {
        return this.tempDir;
    }

    public Boolean getIsDelTempFile() {
        return this.isDelTempFile;
    }

    public void setTempDir(String tempDir) {
        this.tempDir = tempDir;
    }

    public void setIsDelTempFile(Boolean isDelTempFile) {
        this.isDelTempFile = isDelTempFile;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof CommonUploader)) {
            return false;
        } else {
            CommonUploader other = (CommonUploader)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$isDelTempFile = this.getIsDelTempFile();
                Object other$isDelTempFile = other.getIsDelTempFile();
                if (this$isDelTempFile == null) {
                    if (other$isDelTempFile != null) {
                        return false;
                    }
                } else if (!this$isDelTempFile.equals(other$isDelTempFile)) {
                    return false;
                }

                Object this$tempDir = this.getTempDir();
                Object other$tempDir = other.getTempDir();
                if (this$tempDir == null) {
                    if (other$tempDir != null) {
                        return false;
                    }
                } else if (!this$tempDir.equals(other$tempDir)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof CommonUploader;
    }

    public int hashCode() {
        int PRIME =  59;
        int result = 1;
        Object $isDelTempFile = this.getIsDelTempFile();
         result = result * 59 + ($isDelTempFile == null ? 43 : $isDelTempFile.hashCode());
        Object $tempDir = this.getTempDir();
        result = result * 59 + ($tempDir == null ? 43 : $tempDir.hashCode());
        return result;
    }

    public String toString() {
        return "CommonUploader(tempDir=" + this.getTempDir() + ", isDelTempFile=" + this.getIsDelTempFile() + ")";
    }

    public CommonUploader() {
    }

    public CommonUploader(String tempDir, Boolean isDelTempFile) {
        this.tempDir = tempDir;
        this.isDelTempFile = isDelTempFile;
    }
}
package com.shan.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Util {

    private static final char[] hexCode = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String calcMD5(File file) {
        try (InputStream stream = Files.newInputStream(file.toPath(), StandardOpenOption.READ)) {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] buf = new byte[8192];
            int len;
            while ((len = stream.read(buf)) > 0) {
                digest.update(buf, 0, len);
            }
            return toHexString(digest.digest());
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }
    }

    private static String toHexString(byte[] data) {
        StringBuilder r = new StringBuilder(data.length * 2);
        for (byte b : data) {
            r.append(hexCode[(b >> 4) & 0xF]);
            r.append(hexCode[(b & 0xF)]);
        }
        return r.toString().toLowerCase();
    }

    public static String calcMd5(String s) {
        if (s == null || "".equals(s)) {
            return "";
        }
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char[] str = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexCode[byte0 >>> 4 & 0xf];
                str[k++] = hexCode[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Fast MD5 PLUS
     */
    public static String fastMD5(File file) {
        int len = 10000;
        try {
            if(file.length() < 10000000){
                return com.twmacinta.util.MD5.asHex(com.twmacinta.util.MD5.getHash(file));
            }
            byte pond[] =new byte [len];
            RandomAccessFile raf = new RandomAccessFile(file, "r");
            raf.seek(file.length() - len);
            raf.read(pond, 0, len);
            return calcMd5(toHexString(pond));
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static void main(String[] args) {
        File file = new File("D:\\软件\\360极速浏览器.zip");
        String s = Md5Util.fastMD5(file);
        System.out.println(s);
    }

}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.shan.utils;


import java.io.File;
import java.io.IOException;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

public class UploaderUtils {
    private static final Logger logger = LoggerFactory.getLogger(UploaderUtils.class);

    public UploaderUtils() {
    }

    public static String uploadFile(MultipartFile file, String filePath) {
        String fileName = file.getOriginalFilename();
        String newFileName = DateUtils.getInstance().dateFormat(new Date(System.currentTimeMillis()));
        String ext = "";
        if (!StringUtils.isEmpty(fileName)) {
            ext = fileName.substring(fileName.lastIndexOf("."), fileName.length());
        }
        //目标路径+当时时间 yyyy-MM-dd
        String targetFilePath = filePath + File.separator + DateUtils.getInstance().dateFormat10(System.currentTimeMillis());
        logger.info("上传路径{}", targetFilePath);
        System.out.println();
        File targetFile = new File(targetFilePath, newFileName + ext);
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }

        try {
            file.transferTo(targetFile);
        } catch (IllegalStateException var7) {
            var7.printStackTrace();
        } catch (IOException var8) {
            var8.printStackTrace();
        }

        return targetFile.getPath();
    }
}

前端代码 先不放了  因公司保密性  参数放上了可以直接调用

测试

1、检查分片是否存在 

chunk   0

md5Value  e80c5740b90c9366d0ab0b271f8a10c8

moduleName

fileTypeKey   3D/DCV/v1

 2、上传分片

file   选择文件

chunk   0

md5Value  e80c5740b90c9366d0ab0b271f8a10c8

moduleName

fileTypeKey   3D/DCV/v1

上传后看上传的位置   会生成分片文件

 3、合并分片

fileName  test2.xls

chunkCount   1

md5Value  e80c5740b90c9366d0ab0b271f8a10c8

moduleName

fileTypeKey   3D/DCV/v1

合并分片后会删除 临时分片文件  并生成原文件

文件夹上传

前台分为点击上传文件夹和拖拽文件夹

思路:

  * 文件夹上传 前台分为点击上传文件夹和拖拽上传文件夹
     *  1. 对文件夹中的文件循环校验  /uploader/beforeUpload方法
     *  2. 上传文件夹    /uploader/uploadFolder方法

 /**
     * 文件夹上传 前台分为点击上传文件夹和拖拽上传文件夹
     *  1. 对文件夹中的文件循环校验  /uploader/beforeUpload方法
     *  2. 上传文件夹    /uploader/uploadFolder方法
     * @param request
     *  fileId = 在非第一级上传文件时,fileId有值-为所在文件夹的id,上传的路径为  云盘的根路径+上文件的路径
     *  file 上传的文件夹 多个文件
     *  names 前台分为点击上传文件夹和拖拽上传文件夹
     *          点击上传文件夹时,文件的名称中不包含层级关系
     *          拖拽上传文件夹,文件的名称中包含层级关系,names参数为拖拽上传时使用,里面包含所有文件的层级关系
     *          如 names: /360驱动大师目录/下载保存目录/audio_conexant_8.66.83.51_w1064.zip.mem,/360驱动大师目录/下载保存目录/audio_conexant_8.66.83.51_w1064.zip.trt
     * @return
     */
    @PostMapping("uploadFolder")
    public Boolean uploadFolder(HttpServletRequest request) {
        try {
        MultipartHttpServletRequest params = ((MultipartHttpServletRequest) request);
        // 在非第一级上传文件时,fileId有值-为所在文件夹的id,上传的路径为  根路径+上文件的路径
        String fileId = params.getParameter("fileId");
        fileId = StringUtils.isBlank(fileId) ? "0" : fileId;
        String filePath = "0".equals(fileId) ? "" : uploaderService.getFilePathByFileId(fileId);
        String targetDirectoryPath = uploaderService.rootPath() + filePath;

            List<MultipartFile> files = params.getFiles("file");
            String fileParentPaths = params.getParameter("names");
            String[] fileParentPathArr = null;
            if (StringUtils.isNoneBlank(fileParentPaths)) {
                fileParentPathArr = fileParentPaths.split(",");
            }
            //上传人 用户名 用于给上传文件夹赋权限  实际取此处写死模拟
            String userName ="SHANC";
            for (int i = 0; files.size() > i; i++) {
                MultipartFile multipartFile = files.get(i);
                String originalFilename = "/" + multipartFile.getOriginalFilename();
                originalFilename = StringUtils.isNotBlank(fileParentPaths) && fileParentPathArr != null ? fileParentPathArr[i] : originalFilename;
                System.out.println("文件上传路径为:" + targetDirectoryPath + originalFilename);
                File file = new File(targetDirectoryPath + originalFilename);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                try {
                    multipartFile.transferTo(file);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (StringUtils.isNoneBlank(userName)) {
                new Thread(() -> FileUploadUtils.chown(userName, targetDirectoryPath)).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

用的工具类FileUploadUtils

package com.cloud.user.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.system.OsInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DecimalFormat;


@Slf4j
public class FileUploadUtils {

    /**
     * 点
     */
    public static final String DOT = ".";

    /**
     * 直接预览的文件类型(不通过LibreOffice转换)
     */
    public static final String PDF = "pdf";

    private static String transfer(MultipartFile file, File targetFile) {
        try {
            file.transferTo(targetFile);
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
        }
        return targetFile.getPath();
    }

    private static void mkParentFile(File targetFile) {
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
    }

    public static String readableFileSize(long size) {
        if (size <= 0) {
            return "0";
        }
        final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }


    /**
     * 文件上传
     *
     * @param file     文件
     * @param filePath 文件路径
     * @return 文件路径
     */
    public static String upload(MultipartFile file, String filePath) {
        File targetFile = new File(filePath, file.getOriginalFilename().replaceAll(" ", ""));
        mkParentFile(targetFile);
        return transfer(file, targetFile);
    }

    /**
     * 处理文件上传
     *
     * @param file       上传的文件
     * @param targetFile 目标文件
     * @return 上传文件目录
     */
    public static String upload(MultipartFile file, File targetFile) {
        mkParentFile(targetFile);
        return transfer(file, targetFile);
    }

    /**
     * 批量删除文件或文件夹
     *
     * @param filePaths 文件路径
     */
    public static void deletes(String[] filePaths) {
        for (String path : filePaths) {
            delete(path);
        }
    }

    /**
     * 删除文件或文件夹
     *
     * @param filePath 文件路径
     * @return 成功与否
     */
    public static boolean delete(String filePath) {
        return FileUtil.del(new File(filePath));
    }

    /**
     * 处理文件上传
     *
     * @param file        文件
     * @param filePath    文件路径
     * @param newFileName 新文件名称
     * @return 文件大小
     */
    public static Long uploadFileContinue(MultipartFile file, String filePath, String newFileName) {
        // 记录当前文件大小,用于判断文件是否上传完成
        long currentFileLength = 0;
        try {
            String fileName = file.getOriginalFilename();
            RandomAccessFile randomAccessfile;
            // 获取文件的扩展名
            String ext = "";
            if (!StringUtils.isEmpty(fileName)) {
                ext = fileName.substring(fileName.lastIndexOf(DOT));
            }
            File newFile = new File(filePath + newFileName + ext);
            if (!newFile.getParentFile().exists()) {
                newFile.getParentFile().mkdirs();
            }
            // 存在文件
            if (newFile.exists()) {
                randomAccessfile = new RandomAccessFile(newFile, "rw");
            } else {
                // 不存在文件,根据文件标识创建文件
                randomAccessfile = new RandomAccessFile(filePath + newFileName + ext, "rw");
            }
            // 开始文件传输
            InputStream in = file.getInputStream();
            if (randomAccessfile.length() < file.getInputStream().available()) {
                randomAccessfile.seek(randomAccessfile.length());
                in.skip(randomAccessfile.length());
                byte[] b = new byte[1024];
                int n;
                while ((n = in.read(b)) != -1) {
                    randomAccessfile.write(b, 0, n);
                }
            }
            currentFileLength = randomAccessfile.length();
            // 关闭文件
            closeRandomAccessFile(randomAccessfile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return currentFileLength;

    }


    /**
     * 关闭随机访问文件
     *
     * @param randomAccessFile 随机访问的文件
     */
    private static void closeRandomAccessFile(RandomAccessFile randomAccessFile) {
        if (null != randomAccessFile) {
            try {
                randomAccessFile.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 转换PDF文件
     *
     * @param filePath 当前文件路径
     * @return PDF文件转换的全路径
     */
    public static String convertToPDF(String filePath, String targetPath) {
        log.info("filePath:{}", filePath);
        log.info("targetPath:{}", targetPath);
        String windowsPath = "D:/apache-tomcat-8.5.64/webapps/upload/";
        String command = null;
        String pdfPath = null;
        if (isLinux()) {
            command = "/usr/bin/libreoffice6.1 --headless --invisible --convert-to pdf " + filePath + " --outdir " + targetPath;
            pdfPath = targetPath + "/" + changeSuffix(filePath, PDF);
        } else if (isWindows()) {
            command = "cmd /c start soffice --headless --invisible --convert-to pdf:writer_pdf_Export " + filePath + " --outdir " + windowsPath;
            pdfPath = windowsPath + changeSuffix(filePath, PDF);
        }
        System.out.println("pdf command:  " + command);
        Process exec = RuntimeUtil.exec(command);
        try {
            long startTime = System.currentTimeMillis();
            exec.waitFor();
            System.out.println("等待时长:" + (System.currentTimeMillis() - startTime));

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return pdfPath;
    }


    /**
     * 更改文件后缀
     *
     * @param filePath 当前文件路径
     * @param suffix   后缀
     * @return 更改后的文件名
     */
    public static String changeSuffix(String filePath, String suffix) {
        return getPrefix(filePath) + DOT + suffix;
    }


    /**
     * 判断当前OS的类型
     *
     * @return boolean
     */
    public static boolean isWindows() {
        return new OsInfo().isWindows();
    }

    /**
     * 判断当前OS的类型
     *
     * @return boolean
     */
    public static boolean isLinux() {
        return new OsInfo().isLinux();
    }

    /**
     * 根据文件名检查文件类型,忽略大小写
     *
     * @param fileName 文件名,例如hutool.png
     * @param extNames 被检查的扩展名数组,同一文件类型可能有多种扩展名,扩展名不带“.”
     * @return 是否是指定扩展名的类型
     */
    public static boolean isType(String fileName, String... extNames) {
        return FileNameUtil.isType(fileName, extNames);
    }

    /**
     * 获取文件名(包含后缀名)
     *
     * @return 文件名
     */
    public static String getName(String filePath) {
        return FileNameUtil.getName(filePath);
    }

    /**
     * 获取前缀名
     *
     * @return 文件前缀名
     */
    public static String getPrefix(String filePath) {
        return FileNameUtil.getPrefix(filePath);
    }

    /**
     * 获取后缀名(不包括 ".")
     *
     * @return 文件后缀名
     */
    public static String getSuffix(String filePath) {
        return FileNameUtil.getSuffix(filePath);
    }

    /**
     * 文件复制(不覆盖目标文件)
     *
     * @param srcPath  源文件
     * @param destPath 目标文件
     */
    public static File copy(String srcPath, String destPath) {
        return FileUtil.copy(srcPath, destPath, false);
    }

//    public static void main(String[] args) {
//        copy("C:\\Users\\lenovo\\Desktop\\123","C:\\Users\\lenovo\\Desktop\\456");
//    }


    /**
     * 取得OS的文件路径的分隔符(取自系统属性:<code>file.separator</code>)。
     *
     * <p>
     * 例如:Unix为<code>"/"</code>,Windows为<code>"\\"</code>。
     * </p>
     *
     * @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回<code>null</code>。
     */
    public static String getFileSeparator() {
        return new OsInfo().getFileSeparator();
    }

    public static void downloadFile(HttpServletRequest request, HttpServletResponse response, InputStream inputStream, String fileName) {
        try (OutputStream os = response.getOutputStream();
             BufferedInputStream bis = new BufferedInputStream(inputStream);
             BufferedOutputStream bos = new BufferedOutputStream(os)) {
            // 处理下载文件名的乱码问题(根据浏览器的不同进行处理)
            if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
                fileName = new String(fileName.getBytes("GB2312"), "ISO-8859-1");
            } else {
                // 对文件名进行编码处理中文问题
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");// 处理中文文件名的问题
                fileName = new String(fileName.getBytes("UTF-8"), "GBK");// 处理中文文件名的问题
            }
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/x-msdownload");// 不同类型的文件对应不同的MIME类型
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            int bytesRead = 0;
            byte[] buffer = new byte[4096];
            while ((bytesRead = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
                bos.flush();
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }


    /**
     * 删除单个文件
     *
     * @param sPath 被删除文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除目录(文件夹)以及目录下的文件
     *
     * @param path 被删除目录的文件路径
     * @return 目录删除成功返回true,否则返回false
     */
    public static boolean deleteDirectory(String path) {
        File dirFile = new File(path);
        // 如果dir对应的文件不存在,或者不是一个目录,则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {// 删除子文件
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {

                    break;
                }
            } else {// 删除子目录
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {

                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        if (dirFile.delete()) {// 删除当前目录
            return true;
        } else {
            return false;
        }
    }


    public static void chown(String userName, String path) {
        String run = RuntimeUtils.execute("id -u " + userName);
        String run2 = RuntimeUtils.execute("id -g " + userName);
        RuntimeUtils.execute("chown -R " + run + ":" + run2 + " " + path);
    }


}

此处用Apipost模拟下

 

  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值