// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.jeecg.modules.doc.component; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.jeecg.common.util.RedisUtil; import org.jeecg.modules.doc.vo.UploadFile; import org.jeecg.modules.doc.vo.UploadFileResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; @Component public abstract class Uploader { private static final Logger log = LoggerFactory.getLogger(Uploader.class); @Resource RedisLock redisLock; @Resource RedisUtil redisUtil; public Uploader() { } public List upload(HttpServletRequest httpServletRequest) { UploadFile uploadFile = new UploadFile(); uploadFile.setChunkNumber(1); uploadFile.setChunkSize(0L); uploadFile.setTotalChunks(1); uploadFile.setIdentifier(UUID.randomUUID().toString()); List uploadFileResultList = this.upload(httpServletRequest, uploadFile); return uploadFileResultList; } public List upload(HttpServletRequest httpServletRequest, UploadFile uploadFile) { List uploadFileResultList = new ArrayList(); StandardMultipartHttpServletRequest request = (StandardMultipartHttpServletRequest)httpServletRequest; boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (!isMultipart) { throw new UploadException("未包含文件上传域"); } else { try { Iterator iter = request.getFileNames(); while(iter.hasNext()) { List multipartFileList = request.getFiles((String)iter.next()); Iterator var8 = multipartFileList.iterator(); while(var8.hasNext()) { MultipartFile multipartFile = (MultipartFile)var8.next(); QiwenMultipartFile qiwenMultipartFile = new QiwenMultipartFile(multipartFile); UploadFileResult uploadFileResult = this.doUploadFlow(qiwenMultipartFile, uploadFile); uploadFileResultList.add(uploadFileResult); } } return uploadFileResultList; } catch (Exception var12) { throw new UploadException(var12); } } } protected UploadFileResult doUploadFlow(QiwenMultipartFile qiwenMultipartFile, UploadFile uploadFile) { try { this.rectifier(qiwenMultipartFile, uploadFile); UploadFileResult uploadFileResult = this.organizationalResults(qiwenMultipartFile, uploadFile); return uploadFileResult; } catch (Exception var5) { throw new UploadException(var5); } } public abstract void cancelUpload(UploadFile uploadFile); protected abstract void doUploadFileChunk(QiwenMultipartFile qiwenMultipartFile, UploadFile uploadFile) throws IOException; protected abstract UploadFileResult organizationalResults(QiwenMultipartFile qiwenMultipartFile, UploadFile uploadFile); private void rectifier(QiwenMultipartFile qiwenMultipartFile, UploadFile uploadFile) { String key = "QiwenUploader:Identifier:" + uploadFile.getIdentifier() + ":lock"; String current_upload_chunk_number = "QiwenUploader:Identifier:" + uploadFile.getIdentifier() + ":current_upload_chunk_number"; this.redisLock.lock(key); try { if (this.redisUtil.get(current_upload_chunk_number) == null) { this.redisUtil.set(current_upload_chunk_number, 1, 3600000L); } int currentUploadChunkNumber = Integer.parseInt((String)this.redisUtil.get(current_upload_chunk_number)); if (uploadFile.getChunkNumber() != currentUploadChunkNumber) { this.redisLock.unlock(key); Thread.sleep(100L); while(this.redisLock.tryLock(key, 300L, TimeUnit.SECONDS)) { currentUploadChunkNumber = Integer.parseInt((String)this.redisUtil.get(current_upload_chunk_number)); if (uploadFile.getChunkNumber() <= currentUploadChunkNumber) { break; } if (Math.abs(currentUploadChunkNumber - uploadFile.getChunkNumber()) > 2) { log.error("传入的切片数据异常,当前应上传切片为第{}块,传入的为第{}块。", currentUploadChunkNumber, uploadFile.getChunkNumber()); throw new UploadException("传入的切片数据异常"); } this.redisLock.unlock(key); } } log.info("文件名{},正在上传第{}块, 共{}块>>>>>>>>>>", new Object[]{qiwenMultipartFile.getMultipartFile().getOriginalFilename(), uploadFile.getChunkNumber(), uploadFile.getTotalChunks()}); if (uploadFile.getChunkNumber() == currentUploadChunkNumber) { this.doUploadFileChunk(qiwenMultipartFile, uploadFile); log.info("文件名{},第{}块上传成功", qiwenMultipartFile.getMultipartFile().getOriginalFilename(), uploadFile.getChunkNumber()); this.redisUtil.getIncr("QiwenUploader:Identifier:" + uploadFile.getIdentifier() + ":current_upload_chunk_number"); } } catch (Exception var9) { log.error("第{}块上传失败,自动重试", uploadFile.getChunkNumber()); this.redisUtil.set("QiwenUploader:Identifier:" + uploadFile.getIdentifier() + ":current_upload_chunk_number", uploadFile.getChunkNumber(), 3600000L); throw new UploadException("更新远程文件出错", var9); } finally { this.redisLock.unlock(key); } } public synchronized boolean checkUploadStatus(UploadFile param, File confFile) throws IOException { RandomAccessFile confAccessFile = new RandomAccessFile(confFile, "rw"); try { confAccessFile.setLength((long)param.getTotalChunks()); confAccessFile.seek((long)(param.getChunkNumber() - 1)); confAccessFile.write(127); } finally { IOUtils.closeQuietly(confAccessFile); } byte[] completeStatusList = FileUtils.readFileToByteArray(confFile); for(int i = 0; i < completeStatusList.length; ++i) { if (completeStatusList[i] != 127) { return false; } } if (param.getChunkNumber() < param.getTotalChunks()) { log.info("当前块号:{},总块号:{},文件id:{}", param.getChunkNumber(), param.getTotalChunks(),param.getIdentifier()); return false; } confFile.delete(); return true; } public void writeByteDataToFile(byte[] fileData, File file, UploadFile uploadFile) { RandomAccessFile raf = null; try { raf = new RandomAccessFile(file, "rw"); FileChannel fileChannel = raf.getChannel(); long position = (long)(uploadFile.getChunkNumber() - 1) * uploadFile.getChunkSize(); fileChannel.position(position); fileChannel.write(ByteBuffer.wrap(fileData)); fileChannel.force(true); fileChannel.close(); raf.close(); } catch (IOException var8) { throw new UploadException(var8); } } }