package com.artfess.file.attachmentService; import com.artfess.base.attachment.Attachment; import com.artfess.base.attachment.AttachmentService; import com.artfess.base.exception.BaseException; import com.artfess.base.util.AppUtil; import com.artfess.base.util.BeanUtils; import com.artfess.base.util.FileUtil; import com.artfess.base.util.StringUtil; import com.artfess.file.config.FileUploadSetting; import com.artfess.file.params.FlowUploadPropertiesStorageDTO; import com.artfess.file.persistence.manager.FlowUploadPropertiesManager; import com.artfess.file.util.AppFileUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.stereotype.Service; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @Slf4j @Service public class FolderAttachmentServiceImpl implements AttachmentService { public FolderAttachmentServiceImpl() { } public void remove(Attachment attachment, String propertiesId) throws Exception { String attachPath = getAttachPath(propertiesId, attachment); String filePath = attachment.getFilePath(); if (!attachment.getEntryptName()) { filePath = filePath.replace(attachment.getId(), attachment.getFileName()); } String fullPath = attachPath + File.separator + filePath; // 删除文件 FileUtil.deleteFile(fullPath); } @Override public void upload(Attachment attachment, InputStream inputStream, String propertiesId) throws Exception { String filePath = attachment.getFilePath(); String attachPath = getAttachPath(propertiesId, attachment); if (!attachment.getEntryptName()) { filePath = filePath.replace(attachment.getId(), attachment.getFileName()); } filePath = attachPath + File.separator + filePath; if (BeanUtils.isNotEmpty(inputStream)) { FileUtil.createFolderFile(filePath); FileUtil.writeFile(filePath, inputStream); } else { FileUtil.writeByte(filePath, attachment.getBytes()); } } public void download(Attachment attachment, OutputStream outStream, String propertiesId) throws Exception { String filePath = null; if(StringUtil.isEmpty(attachment.getZoneTotal()) || "0".equals(attachment.getZoneTotal())) { filePath = getAttachPath(propertiesId,attachment); String attachPath = getAttachPath(propertiesId,attachment); if(!attachment.getEntryptName()){ filePath = filePath.replace(attachment.getId(), attachment.getFileName()); } filePath=attachPath+File.separator+filePath; }else{ FileUploadSetting fileUploadSetting = AppUtil.getBean(FileUploadSetting.class); String basepath = fileUploadSetting.getBasepath(); filePath = basepath + File.separator + attachment.getMd5Value() + File.separator + attachment.getFileName(); } String fullPath = filePath.replace("/", File.separator); File file = new File(fullPath); if (file.exists()) { FileInputStream inputStream = null; try { inputStream = new FileInputStream(fullPath); byte[] b = new byte[1024]; int i = 0; while ((i = inputStream.read(b)) > 0) { outStream.write(b, 0, i); } outStream.flush(); } catch (Exception e) { throw e; } finally { if (inputStream != null) { inputStream.close(); inputStream = null; } if (outStream != null) { outStream.close(); outStream = null; } } } else { throw new RuntimeException("该附件不存在"); } } @Override public String getStoreType() { return "folder"; } @Override public boolean chekckFile(Attachment attachment, String propertiesId) { String filePath = null; if(StringUtil.isEmpty(attachment.getZoneTotal()) || "0".equals(attachment.getZoneTotal())) { filePath = getAttachPath(propertiesId,attachment); String attachPath = getAttachPath(propertiesId,attachment); if(!attachment.getEntryptName()){ filePath = filePath.replace(attachment.getId(), attachment.getFileName()); } filePath=attachPath+File.separator+filePath; }else{ FileUploadSetting fileUploadSetting = AppUtil.getBean(FileUploadSetting.class); String basepath = fileUploadSetting.getBasepath(); filePath = basepath + File.separator + attachment.getMd5Value() + File.separator + attachment.getFileName(); } String fullPath = filePath.replace("/", File.separator); File file = new File(fullPath); return file.exists(); } /** * 获取文件上传根目录 * * @param propertiesId * @return */ private String getAttachPath(String propertiesId, Attachment attachment) { FlowUploadPropertiesStorageDTO uploadProperties = getUploadProperties(propertiesId); String attachPath = ""; if (BeanUtils.isNotEmpty(uploadProperties)) { attachPath = uploadProperties.getLocation(); attachment.setEntryptName(uploadProperties.getEncryptName() == 0 ? false : true); } else { attachPath = AppFileUtil.getAttachPath(); } return attachPath; } /** * 根据配置id获取文件上传配置 * * @param propertiesId * @return */ private FlowUploadPropertiesStorageDTO getUploadProperties(String propertiesId) { if (StringUtil.isEmpty(propertiesId)) { return null; } FlowUploadPropertiesManager uploadPropertiesManager = AppUtil.getBean(FlowUploadPropertiesManager.class); return uploadPropertiesManager.getById(propertiesId); } @Override public byte[] getFileBytes(Attachment sysFile) throws Exception { String filePath = sysFile.getFilePath(); String fullPath = StringUtil.trimSufffix(AppFileUtil.getAttachPath(), File.separator) + File.separator + filePath.replace("/", File.separator); File file = new File(fullPath); if (file.exists()) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); FileInputStream inputStream = null; try { inputStream = new FileInputStream(fullPath); byte[] b = new byte[1024]; int i = 0; while ((i = inputStream.read(b)) > 0) { outStream.write(b, 0, i); } outStream.flush(); return outStream.toByteArray(); } catch (Exception e) { throw e; } finally { if (inputStream != null) { inputStream.close(); inputStream = null; } if (outStream != null) { outStream.close(); outStream = null; } } } else { throw new RuntimeException("该附件不存在"); } } @Override public String initMultiPartUpload(Attachment attachment) { //初始化创建文件夹 FileUploadSetting fileUploadSetting = AppUtil.getBean(FileUploadSetting.class); String chunkFolder = fileUploadSetting.getBasepath() + File.separator + attachment.getMd5Value(); File file = new File(chunkFolder); if (!file.exists()) { file.mkdirs(); } return attachment.getMd5Value(); } @Override public String getChunkUrl(Attachment attachment, Integer partNumber, String uploadId) { FileUploadSetting fileUploadSetting = AppUtil.getBean(FileUploadSetting.class); String chunkFolder = fileUploadSetting.getBasepath() + File.separator + attachment.getMd5Value(); return chunkFolder + File.separator + partNumber; } @Override public boolean mergeMultipartUpload(Attachment attachment, String uploadId, int realyPartNumber) { log.info("分片合并==================================》"); // 块文件目录 FileUploadSetting fileUploadSetting = AppUtil.getBean(FileUploadSetting.class); File chunkFolder = new File(fileUploadSetting.getBasepath() + File.separator + attachment.getMd5Value()); // 合并后的文件 File mergeFile = new File(fileUploadSetting.getBasepath() + File.separator + attachment.getMd5Value() + File.separator + attachment.getFileName()); // 取出所有分块文件 File[] files = chunkFolder.listFiles(); // 将数组转成list List filesList = Arrays.asList(files); // 若上传的分片少于实际分片数量,不能合并 if (filesList.size() < realyPartNumber) { // 分片文件不够,不能合并 log.info(">>>>>>>>>>{}分片文件不够,不能合并", uploadId); throw new BaseException("分片文件不够,不能合并!"); } long startTime = System.currentTimeMillis(); // 对分块文件排序 Collections.sort(filesList, new Comparator() { @Override public int compare(File o1, File o2) { // 将分块文件按文件名称1、2、3、4、5...排序 return Integer.parseInt(o1.getName()) - Integer.parseInt(o2.getName()); } }); // 向合并文件写的流 RandomAccessFile raf_rw = null; try { raf_rw = new RandomAccessFile(mergeFile, "rw"); // 缓冲区 byte[] bytes = new byte[1024]; // 遍历分块文件 for (File file : filesList) { // 读分块的流 RandomAccessFile raf_r = new RandomAccessFile(file, "r"); int len = -1; // 从分块中读取数据到缓冲区 while ((len = raf_r.read(bytes)) != -1) { // 将缓冲区的数据写入合并文件 raf_rw.write(bytes, 0, len); } raf_r.close(); } raf_rw.close(); return true; } catch (IOException e) { e.printStackTrace(); return false; } } }