快捷搜索:  汽车  科技

java大文件上传解析(java大文件分片上传)

java大文件上传解析(java大文件分片上传)package com.mracale.controller; import com.mracale.dto.FileDto; import com.mracale.dto.ResponseDto; import com.mracale.util.Base64ToMultipartFile; import com.mracale.util.UuidUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.text.SimpleDateFormat; i

java大文件上传解析(java大文件分片上传)(1)

前端部分

md5.js md5加密

var KEY = "COURSE"; /* * Configurable variables. You may need to tweak these to be compatible with * the server-side but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_md5(s){ return binl2hex(core_md5(str2binl(s) s.length * chrsz));} function b64_md5(s){ return binl2b64(core_md5(str2binl(s) s.length * chrsz));} function str_md5(s){ return binl2str(core_md5(str2binl(s) s.length * chrsz));} function hex_hmac_md5(key data) { return binl2hex(core_hmac_md5(key data)); } function b64_hmac_md5(key data) { return binl2b64(core_hmac_md5(key data)); } function str_hmac_md5(key data) { return binl2str(core_hmac_md5(key data)); } /* * Perform a simple self-test to see if the VM is working */ function md5_vm_test() { return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; } /* * Calculate the MD5 of an array of little-endian words and a bit length */ function core_md5(x len) { /* append padding */ x[len >> 5] |= 0x80 << ((len) % 32); x[(((len 64) >>> 9) << 4) 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for(var i = 0; i < x.length; i = 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a b c d x[i 0] 7 -680876936); d = md5_ff(d a b c x[i 1] 12 -389564586); c = md5_ff(c d a b x[i 2] 17 606105819); b = md5_ff(b c d a x[i 3] 22 -1044525330); a = md5_ff(a b c d x[i 4] 7 -176418897); d = md5_ff(d a b c x[i 5] 12 1200080426); c = md5_ff(c d a b x[i 6] 17 -1473231341); b = md5_ff(b c d a x[i 7] 22 -45705983); a = md5_ff(a b c d x[i 8] 7 1770035416); d = md5_ff(d a b c x[i 9] 12 -1958414417); c = md5_ff(c d a b x[i 10] 17 -42063); b = md5_ff(b c d a x[i 11] 22 -1990404162); a = md5_ff(a b c d x[i 12] 7 1804603682); d = md5_ff(d a b c x[i 13] 12 -40341101); c = md5_ff(c d a b x[i 14] 17 -1502002290); b = md5_ff(b c d a x[i 15] 22 1236535329); a = md5_gg(a b c d x[i 1] 5 -165796510); d = md5_gg(d a b c x[i 6] 9 -1069501632); c = md5_gg(c d a b x[i 11] 14 643717713); b = md5_gg(b c d a x[i 0] 20 -373897302); a = md5_gg(a b c d x[i 5] 5 -701558691); d = md5_gg(d a b c x[i 10] 9 38016083); c = md5_gg(c d a b x[i 15] 14 -660478335); b = md5_gg(b c d a x[i 4] 20 -405537848); a = md5_gg(a b c d x[i 9] 5 568446438); d = md5_gg(d a b c x[i 14] 9 -1019803690); c = md5_gg(c d a b x[i 3] 14 -187363961); b = md5_gg(b c d a x[i 8] 20 1163531501); a = md5_gg(a b c d x[i 13] 5 -1444681467); d = md5_gg(d a b c x[i 2] 9 -51403784); c = md5_gg(c d a b x[i 7] 14 1735328473); b = md5_gg(b c d a x[i 12] 20 -1926607734); a = md5_hh(a b c d x[i 5] 4 -378558); d = md5_hh(d a b c x[i 8] 11 -2022574463); c = md5_hh(c d a b x[i 11] 16 1839030562); b = md5_hh(b c d a x[i 14] 23 -35309556); a = md5_hh(a b c d x[i 1] 4 -1530992060); d = md5_hh(d a b c x[i 4] 11 1272893353); c = md5_hh(c d a b x[i 7] 16 -155497632); b = md5_hh(b c d a x[i 10] 23 -1094730640); a = md5_hh(a b c d x[i 13] 4 681279174); d = md5_hh(d a b c x[i 0] 11 -358537222); c = md5_hh(c d a b x[i 3] 16 -722521979); b = md5_hh(b c d a x[i 6] 23 76029189); a = md5_hh(a b c d x[i 9] 4 -640364487); d = md5_hh(d a b c x[i 12] 11 -421815835); c = md5_hh(c d a b x[i 15] 16 530742520); b = md5_hh(b c d a x[i 2] 23 -995338651); a = md5_ii(a b c d x[i 0] 6 -198630844); d = md5_ii(d a b c x[i 7] 10 1126891415); c = md5_ii(c d a b x[i 14] 15 -1416354905); b = md5_ii(b c d a x[i 5] 21 -57434055); a = md5_ii(a b c d x[i 12] 6 1700485571); d = md5_ii(d a b c x[i 3] 10 -1894986606); c = md5_ii(c d a b x[i 10] 15 -1051523); b = md5_ii(b c d a x[i 1] 21 -2054922799); a = md5_ii(a b c d x[i 8] 6 1873313359); d = md5_ii(d a b c x[i 15] 10 -30611744); c = md5_ii(c d a b x[i 6] 15 -1560198380); b = md5_ii(b c d a x[i 13] 21 1309151649); a = md5_ii(a b c d x[i 4] 6 -145523070); d = md5_ii(d a b c x[i 11] 10 -1120210379); c = md5_ii(c d a b x[i 2] 15 718787259); b = md5_ii(b c d a x[i 9] 21 -343485551); a = safe_add(a olda); b = safe_add(b oldb); c = safe_add(c oldc); d = safe_add(d oldd); } return Array(a b c d); } /* * These functions implement the four basic operations the algorithm uses. */ function md5_cmn(q a b x s t) { return safe_add(bit_rol(safe_add(safe_add(a q) safe_add(x t)) s) b); } function md5_ff(a b c d x s t) { return md5_cmn((b & c) | ((~b) & d) a b x s t); } function md5_gg(a b c d x s t) { return md5_cmn((b & d) | (c & (~d)) a b x s t); } function md5_hh(a b c d x s t) { return md5_cmn(b ^ c ^ d a b x s t); } function md5_ii(a b c d x s t) { return md5_cmn(c ^ (b | (~d)) a b x s t); } /* * Calculate the HMAC-MD5 of a key and some data */ function core_hmac_md5(key data) { var bkey = str2binl(key); if(bkey.length > 16) bkey = core_md5(bkey key.length * chrsz); var ipad = Array(16) opad = Array(16); for(var i = 0; i < 16; i ) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = core_md5(ipad.concat(str2binl(data)) 512 data.length * chrsz); return core_md5(opad.concat(hash) 512 128); } /* * Add integers wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x y) { var lsw = (x & 0xFFFF) (y & 0xFFFF); var msw = (x >> 16) (y >> 16) (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * Convert a string to an array of little-endian words * If chrsz is ASCII characters >255 have their hi-byte silently ignored. */ function str2binl(str) { var bin = Array(); var mask = (1 << chrsz) - 1; for(var i = 0; i < str.length * chrsz; i = chrsz) bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i2); return bin; } /* * Convert an array of little-endian words to a string */ function binl2str(bin) { var str = ""; var mask = (1 << chrsz) - 1; for(var i = 0; i < bin.length * 32; i = chrsz) str = String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); return str; } /* * Convert an array of little-endian words to a hex string. */ function binl2hex(binarray) { var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for(var i = 0; i < binarray.length * 4; i ) { str = hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 4)) & 0xF) hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); } return str; } /* * Convert an array of little-endian words to a base-64 string */ function binl2b64(binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /"; var str = ""; for(var i = 0; i < binarray.length * 4; i = 3) { var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) | (((binarray[i 1 >> 2] >> 8 * ((i 1)%4)) & 0xFF) << 8 ) | ((binarray[i 2 >> 2] >> 8 * ((i 2)%4)) & 0xFF); for(var j = 0; j < 4; j ) { if(i * 8 j * 6 > binarray.length * 32) str = b64pad; else str = tab.charAt((triplet >> 6*(3-j)) & 0x3F); } } return str; }

tool.js 工具

Tool = { /** * 空校验 null或""都返回true */ isEmpty: function (obj) { if ((typeof obj == 'string')) { return !obj || obj.replace(/\s /g "") == "" } else { return (!obj || JSON.stringify(obj) === "{}" || obj.length === 0); } } /** * 非空校验 */ isNotEmpty: function (obj) { return !this.isEmpty(); } /** * 长度校验 */ isLength: function (str min max) { return $.trim(str).length >= min && $.trim(str).length <= max; } /** * 时间格式化,date为空时取当前时间 */ dateFormat: function (format date) { let result; if (!date) { date = new Date(); } const option = { "y ": date.getFullYear().toString() // 年 "M ": (date.getMonth() 1).toString() // 月 "d ": date.getDate().toString() // 日 "h ": date.getHours().toString() // 时 "m ": date.getMinutes().toString() // 分 "s ": date.getSeconds().toString() // 秒 }; for (let i in option) { result = new RegExp("(" i ")").exec(format); if (result) { format = format.replace(result[1] (result[1].length == 1) ? (option[i]) : (option[i].padStart(result[1].length "0"))) } } return format; } /** * 移除对象数组中的对象 * @param array * @param obj * @returns {number} */ removeObj: function (array obj) { let index = -1; for (let i = 0; i < array.length; i ) { if (array[i] === obj) { array.splice(i 1); index = i; break; } } return index; } /** * 10进制转62进制 * @param number * @returns {string} * @private */ _10to62: function (number) { let chars = '0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ'; let radix = chars.length; let arr = []; do { let mod = number % radix; number = (number - mod) / radix; arr.unshift(chars[mod]); } while (number); return arr.join(''); } };

index.html 上传页面

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="" th:src="@{/js/md5.js}"></script> <script src="" th:src="@{/js/tool.js}"></script> </head> <body> <button type="button" class="btn btn-default" onclick="selectImg()">文件上传</button> <input class="hidden" multiple type="file" onchange="uploadImage()" id="file-upload-input"> <table class="table table-bordered tinfo" style="display: none;"> <thead> <tr> <th>文件名称</th> <th>文件大小</th> <th>上传进度</th> </tr> </thead> <tbody id="upinfo"> </tbody> </table> <div class="progress progress-striped active" style="display: none;"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 40%;"> <span class="sr-only">40% 完成</span> </div> </div> <script> function selectImg() { $("#file-upload-input").trigger("click"); } function uploadImage (){ let file = document.getElementById("file-upload-input").files; for (let i=0;i<file.length;i ){ let info = '<tr>\n' ' <td>' file[i].name '</td>\n' ' <td>' parseFloat(file[i].size/1024/1024).toFixed(2) "M" '</td>\n' ' <td class="index' i '">' '进行中' '</td>\n' ' </tr>'; $("#upinfo").append(info); $(".tinfo").css("display" "block"); multiple_upload(file[i] i); } } //多文件上传 file 文件信息 curr 当前文件的索引 function multiple_upload(file curr) { // 文件分片 var shardSize = 10 * 1024 * 1024; //以5MB为一个分片 var shardIndex = 1; //分片索引,1表示第1个分片 var size = file.size; // 文件大小 var shardTotal = Math.ceil(size / shardSize); //总片数 var suffix = file.name.substring(file.name.lastIndexOf(".") 1);//文件后缀 // 生成文件标识,标识多次上传的是不是同一个文件 var key = hex_md5(file.name file.lastModified file.lastModifiedDate file.webkitRelativePath file.size file.type); var key10 = parseInt(key 16); var key62 = Tool._10to62(key10); console.log("文件的唯一表示" file.name key key10 key62); var param = { 'shardIndex': shardIndex 'shardSize': shardSize 'shardTotal': shardTotal 'use': "file" 'name': file.name 'suffix': suffix 'size': file.size 'key': key62 }; //文件上传 upload_file(param file curr); } // 文件上传到服务器 function upload_file(param file curr) { // 将图片转为base64进行传输 var fileReader = new FileReader(); let fileShard = getFileShard(param.shardIndex param.shardSize file); let progress = parseInt((param.shardIndex - 1) * 100 / param.shardTotal); $(".index" curr).html(progress "%"); fileReader.onload = function(e) { var base64 = e.target.result; console.log("base64:" base64); param.shard = base64; $.ajax({ url: "/admin/upload" type: "POST" data: JSON.stringify(param) contentType: 'application/json' /** * 必须false才会避开jQuery对 formdata 的默认处理 * XMLHttpRequest会对 formdata 进行正确的处理 */ processData: false success: function (data) { if (param.shardIndex < param.shardTotal) { // 上传下一个分片 param.shardIndex = param.shardIndex 1; //大文件递归上传 upload_file(param file curr); } else { $(".index" curr).html("已完成"); console.log("上传完成") } } error: function () { alert("上传失败!"); } }); }; fileReader.readAsDataURL(fileShard); } //获取文件的分片 function getFileShard (shardIndex shardSize file) { let start = (shardIndex - 1) * shardSize; //当前分片起始位置 let end = Math.min(file.size start shardSize); //当前分片结束位置 let fileShard = file.slice(start end); //从文件中截取当前的分片数据 return fileShard; } </script> </body> </html>后端部分

FileDto.java 接收文件上传参数

package com.mracale.dto; import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; public class FileDto { /** * id */ private String id; /** * 相对路径 */ private String path; /** * 文件名 */ private String name; /** * 后缀 */ private String suffix; /** * 大小|字节B */ private Integer size; /** * 用途 */ private String use; /** * 创建时间 */ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss" timezone = "GMT 8") private Date createdAt; /** * 修改时间 */ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss" timezone = "GMT 8") private Date updatedAt; private Integer shardIndex; private Integer shardSize; private Integer shardTotal; private String key; /** * base64 */ private String shard; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSuffix() { return suffix; } public void setSuffix(String suffix) { this.suffix = suffix; } public Integer getSize() { return size; } public void setSize(Integer size) { this.size = size; } public String getUse() { return use; } public void setUse(String use) { this.use = use; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } public Date getUpdatedAt() { return updatedAt; } public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } public Integer getShardIndex() { return shardIndex; } public void setShardIndex(Integer shardIndex) { this.shardIndex = shardIndex; } public Integer getShardSize() { return shardSize; } public void setShardSize(Integer shardSize) { this.shardSize = shardSize; } public Integer getShardTotal() { return shardTotal; } public void setShardTotal(Integer shardTotal) { this.shardTotal = shardTotal; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getShard() { return shard; } public void setShard(String shard) { this.shard = shard; } @Override public String toString() { final StringBuffer sb = new StringBuffer("FileDto{"); sb.append("id='").append(id).append('\''); sb.append(" path='").append(path).append('\''); sb.append(" name='").append(name).append('\''); sb.append(" suffix='").append(suffix).append('\''); sb.append(" size=").append(size); sb.append(" use='").append(use).append('\''); sb.append(" createdAt=").append(createdAt); sb.append(" updatedAt=").append(updatedAt); sb.append(" shardIndex=").append(shardIndex); sb.append(" shardSize=").append(shardSize); sb.append(" shardTotal=").append(shardTotal); sb.append(" key='").append(key).append('\''); sb.append(" shard='").append(shard).append('\''); sb.append('}'); return sb.toString(); } }

ResponseDto.java 前端返回类

package com.mracale.dto; public class ResponseDto<T> { /** * 业务上的成功或失败 */ private boolean success = true; /** * 返回码 */ private String code; /** * 返回信息 */ private String message; /** * 返回泛型数据,自定义类型 */ private T content; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public boolean getSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getContent() { return content; } public void setContent(T content) { this.content = content; } @Override public String toString() { final StringBuffer sb = new StringBuffer("ResponseDto{"); sb.append("success=").append(success); sb.append(" code='").append(code).append('\''); sb.append(" message='").append(message).append('\''); sb.append(" content=").append(content); sb.append('}'); return sb.toString(); } }

Base64ToMultipartFile.java 前端base64上传,后端接收base64转为Multipart

package com.mracale.util; import org.springframework.web.multipart.MultipartFile; import sun.misc.BASE64Decoder; import java.io.*; public class Base64ToMultipartFile implements MultipartFile { private final byte[] imgContent; private final String header; public Base64ToMultipartFile(byte[] imgContent String header) { this.imgContent = imgContent; this.header = header.split(";")[0]; } @Override public String getName() { // TODO - implementation depends on your requirements return System.currentTimeMillis() Math.random() "." header.split("/")[1]; } @Override public String getOriginalFilename() { // TODO - implementation depends on your requirements return System.currentTimeMillis() (int) Math.random() * 10000 "." header.split("/")[1]; } @Override public String getContentType() { // TODO - implementation depends on your requirements return header.split(":")[1]; } @Override public boolean isEmpty() { return imgContent == null || imgContent.length == 0; } @Override public long getSize() { return imgContent.length; } @Override public byte[] getBytes() throws IOException { return imgContent; } @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(imgContent); } @Override public void transferTo(File dest) throws IOException IllegalStateException { new FileOutputStream(dest).write(imgContent); } public static MultipartFile base64ToMultipart(String base64) { try { String[] baseStrs = base64.split(" "); BASE64Decoder decoder = new BASE64Decoder(); byte[] b = new byte[0]; b = decoder.decodeBuffer(baseStrs[1]); for(int i = 0; i < b.length; i) { if (b[i] < 0) { b[i] = 256; } } return new Base64ToMultipartFile(b baseStrs[0]); } catch (IOException e) { e.printStackTrace(); return null; } } }

UuidUtil.java

package com.mracale.util; import java.util.UUID; public class UuidUtil { public static String[] chars = new String[] { "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" }; /** * 获取短UUID * @return */ public static String getShortUuid() { StringBuffer shortBuffer = new StringBuffer(); String uuid = UuidUtil.getUuid(); for (int i = 0; i < 8; i ) { String str = uuid.substring(i * 4 i * 4 4); int x = Integer.parseInt(str 16); shortBuffer.append(chars[x % 0x3E]); // 对62取余 } return shortBuffer.toString(); } /** * 获得32位UUID */ public static String getUuid(){ String uuid = UUID.randomUUID().toString(); //去掉“-”符号 return uuid.replaceAll("-" ""); } public static void main(String[] args) { System.out.println(getShortUuid()); } }

UploadController.java 控制器,接收前端文件上传

package com.mracale.controller; import com.mracale.dto.FileDto; import com.mracale.dto.ResponseDto; import com.mracale.util.Base64ToMultipartFile; import com.mracale.util.UuidUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date; @RequestMapping("/admin") @RestController public class UploadController { private static final Logger LOG = LoggerFactory.getLogger(UploadController.class); private static final String storePath = "D:/phpstudy_pro/WWW/java/springboot-test/file/"; @RequestMapping("/upload1") public ResponseDto upload(@RequestParam MultipartFile file) throws Exception { LOG.info("上传文件开始:{}" file); LOG.info(file.getOriginalFilename()); LOG.info(String.valueOf(file.getSize())); // 保存文件到本地 String fileName = file.getOriginalFilename(); String key = UuidUtil.getShortUuid(); Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/"); String format = simpleDateFormat.format(date); LOG.info("日期信息:" format); String fullPath = storePath format; if (!new File(fullPath).exists()){ new File(fullPath).mkdirs(); } fullPath = fullPath key "-" fileName; File dest = new File(fullPath); try{ file.transferTo(dest); }catch (IOException e){ e.printStackTrace(); } LOG.info(dest.getAbsolutePath()); ResponseDto responseDto = new ResponseDto(); responseDto.setContent("http://127.0.0.1:8080/f/" format key "-" fileName); return responseDto; } @RequestMapping("/upload") public ResponseDto upload(@RequestBody FileDto fileDto) throws Exception { LOG.info("上传文件开始"); String use = fileDto.getUse(); String key = fileDto.getKey(); String suffix = fileDto.getSuffix(); String shardBase64 = fileDto.getShard(); MultipartFile shard = Base64ToMultipartFile.base64ToMultipart(shardBase64); // 保存文件到本地 Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/"); String format = simpleDateFormat.format(date); LOG.info("日期信息:" format); String fullPath = storePath format; if (!new File(fullPath).exists()){ new File(fullPath).mkdirs(); } String path = new StringBuffer(fullPath) .append(key) .append(".") .append(suffix) .toString(); // course\6sfSqfOwzmik4A4icMYuUe.mp4 String localPath = new StringBuffer(path) .append(".") .append(fileDto.getShardIndex()) .toString(); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1 File dest = new File(localPath); shard.transferTo(dest); LOG.info(dest.getAbsolutePath()); LOG.info("保存文件记录开始"); fileDto.setPath(path); // 合并分片 if (fileDto.getShardIndex().equals(fileDto.getShardTotal())) { this.merge(fileDto); } ResponseDto<Object> responseDto = new ResponseDto<>(); return responseDto; } public void merge(FileDto fileDto) throws Exception { LOG.info("合并分片开始"); String path = fileDto.getPath(); //http://127.0.0.1:9000/file/f/course\6sfSqfOwzmik4A4icMYuUe.mp4 Integer shardTotal = fileDto.getShardTotal(); File newFile = new File(path); FileOutputStream outputStream = new FileOutputStream(newFile true);//文件追加写入 FileInputStream fileInputStream = null;//分片文件 byte[] byt = new byte[10 * 1024 * 1024]; int len; try { for (int i = 0; i < shardTotal; i ) { // 读取第i个分片 fileInputStream = new FileInputStream(new File( path "." (i 1))); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1 while ((len = fileInputStream.read(byt)) != -1) { outputStream.write(byt 0 len); } } } catch (IOException e) { LOG.error("分片合并异常" e); } finally { try { if (fileInputStream != null) { fileInputStream.close(); } outputStream.close(); LOG.info("IO流关闭"); } catch (Exception e) { LOG.error("IO流关闭" e); } } LOG.info("合并分片结束"); // 删除分片 LOG.info("删除分片开始"); File file = null; String filePath = ""; for (int i = 0; i < shardTotal; i ) { filePath = path "." (i 1); file = new File(filePath); System.gc(); boolean result = file.delete(); LOG.info("删除{},{}" filePath result ? "成功" : "失败"); } LOG.info("删除分片结束"); } }



猜您喜欢: