package com.tiesheng.web.service; import cn.hutool.core.io.FileTypeUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; import com.tiesheng.util.exception.ApiException; import com.tiesheng.util.pojos.FileUploadPath; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; /** * @author hao */ @Service public class FileUploadService { @Autowired TieshengWebConfigurer tieshengWebConfigurer; /////////////////////////////////////////////////////////////////////////// // 方法 /////////////////////////////////////////////////////////////////////////// /** * 保存文件 * * @param file */ public String saveMultipartFile(MultipartFile file) { try { String fileHttpPath = tieshengWebConfigurer.uploadFileCustomize(file); if (!StrUtil.isEmpty(fileHttpPath)) { return fileHttpPath; } String fileType = FileTypeUtil.getType(file.getInputStream(), file.getOriginalFilename()); tieshengWebConfigurer.uploadFileCheck(fileType); FileUploadPath filePath = FileUploadPath.random(fileType); InputStream stream = file.getInputStream(); FileUtil.writeFromStream(stream, filePath.getAbsolutePath()); IoUtil.close(stream); return tieshengWebConfigurer.uploadFileDeal(filePath.getHttpPath()); } catch (Exception e) { throw new ApiException("文件流读取失败:" + e.getMessage()); } } /////////////////////////////////////////////////////////////////////////// // 文件分包上传 /////////////////////////////////////////////////////////////////////////// /** * 检查待上传文件是否存在 * * @param fileExt */ public void chunkStart(String fileExt) { tieshengWebConfigurer.uploadFileCheck(fileExt); } /** * 检查块文件 * * @param fileMd5 * @param chunk * @return */ public boolean chunkCheck(String fileMd5, Integer chunk) { FileUploadPath folder = FileUploadPath.folder(fileMd5); File chunkFile = FileUtil.file(folder.getAbsolutePath(), chunk.toString()); return chunkFile.exists(); } /** * 块文件上传 * * @param file * @param fileMd5 * @param chunk */ public void chunkUpload(MultipartFile file, String fileMd5, Integer chunk) { if (file == null) { throw new ApiException("请选择文件后上传"); } try { // 块文件 FileUploadPath folder = FileUploadPath.folder(fileMd5); File chunkfile = new File(folder.getAbsolutePath(), chunk.toString()); InputStream stream = file.getInputStream(); FileUtil.writeFromStream(stream, chunkfile); IoUtil.close(stream); } catch (Exception ignored) { throw new ApiException("块文件上传失败"); } } /** * 合并块文件 * * @param fileMd5 */ public String chunkMerge(String fileMd5, String fileExt) { // 1,获取文件块的目录 FileUploadPath folder = FileUploadPath.folder(fileMd5); // 2,如果目录不存在 if (!FileUtil.exist(folder.getAbsolutePath())) { throw new ApiException("请先上传文件块"); } // 3,生成保存文件的路径 FileUploadPath uploadPath = FileUploadPath.random(fileExt); // 4,获取块文件,此列表是已经排好序的列表 List chunkFiles = getSortedChunkFiles(new File(folder.getAbsolutePath())); // 5,合并文件 File newFile = FileUtil.newFile(uploadPath.getAbsolutePath()); for (File file : chunkFiles) { byte[] bytes = FileUtil.readBytes(file); FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true); } // 6,删除块文件目录 FileUtil.del(folder.getAbsolutePath()); return tieshengWebConfigurer.uploadFileDeal(uploadPath.getHttpPath()); } /** * 获取所有块文件 * * @param chunkFileFolder * @return */ private List getSortedChunkFiles(File chunkFileFolder) { //获取路径下的所有块文件 File[] chunkFiles = chunkFileFolder.listFiles(); if (chunkFiles == null) { return new ArrayList<>(); } //将文件数组转成list,并排序 List chunkFileList = new ArrayList<>(Arrays.asList(chunkFiles)); //排序 chunkFileList.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getName()))); return chunkFileList; } }