package dynamic.sys; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import dm.jdbc.util.StringUtil; import microbee.http.annotation.Controller; import microbee.http.annotation.ExcludeL; import microbee.http.apps.dynamic.HoContext; import microbee.http.apps.dynamic.WsContext; import microbee.http.modulars.smcms.SmMessage; import microbee.http.utills.CompdFileUtil; import microbee.http.utills.GlobalData; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @author quanjl * @date 2022/9/27 * 描述:文件上传 */ @Controller public class Con_FileUpload { public String upload(HoContext hoContext) { /* 获取参数 * {actype=10,ggggggg={"fileSize":51981,"fileType":"image/png","suffix":"png","tmpPath":"/tmp/FUp_2075739431627410001_upload"}} * */ Map dataMap = hoContext.httpRequest.getParams(); /* * 获取图片信息 * {"fileSize":51981,"fileType":"image/png","suffix":"png","tmpPath":"/tmp/FUp_2075739431627410001_upload"} * */ String dd = dataMap.get("ggggggg"); System.out.println("------ " + dd); // 获取信息,拼接文件名 JSONObject object = JSON.parseObject(dd); // 路径 String tmpPath = null; Map map = new HashMap(); try { tmpPath = object.get("tmpPath").toString(); } catch (Exception e) { e.printStackTrace(); return "{\"msg\": \"未查询到文件源路径,请重新上传!\"}"; } // 后缀 String suffix = object.get("suffix").toString(); // 时间戳 long currentTimeMillis = System.currentTimeMillis(); // 时间格式 SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat hmsS = new SimpleDateFormat("HHmmssSSS"); String ymd_str = ymd.format(new Date(currentTimeMillis)); String hmsS_str = hmsS.format(new Date(currentTimeMillis)); /** * 文件另存为路径 * rootPath:根目录 * filePath:文件所在目录(服务器路径) * returnPath:返回给前端的路径 * newPath:文件总目录 */ String rootPath = GlobalData.server_conf_dom4j.getUploaddir(); String filePath = File.separator + "uploads" + File.separator + ymd_str + File.separator + hmsS_str + "." + suffix; String returnPath = "/uploads/" + ymd_str + "/" + hmsS_str + "." + suffix; String newPath = rootPath + filePath; try { // 读取文件、写入文件 File oldFile = new File(tmpPath); File file = new File(newPath); // 判断文件夹是否存在,不存在则创建 if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } FileInputStream in = new FileInputStream(oldFile); FileOutputStream out = new FileOutputStream(file); int fileSize = Integer.parseInt(object.get("fileSize").toString()); byte[] buffer = new byte[fileSize]; if (fileSize > 0) { while ((in.read(buffer)) != -1) { out.write(buffer); } } // 删除缓存旧文件 oldFile.delete(); map.put("error", 0); map.put("url", returnPath); map.put("message", "上传成功!"); return JSON.toJSONString(map); } catch (Exception e) { map.put("error", 1); map.put("url", ""); map.put("message", "上传失败!"); e.printStackTrace(); } return JSON.toJSONString(map); } /** * 上传接口,编辑器使用(修改了参数名及返回值) * @param hoContext * @return */ public String uploadOfEditor(HoContext hoContext) { /* 获取参数 * {actype=10,ggggggg={"fileSize":51981,"fileType":"image/png","suffix":"png","tmpPath":"/tmp/FUp_2075739431627410001_upload"}} * */ Map dataMap = hoContext.httpRequest.getParams(); /* * 获取图片信息 * {"fileSize":51981,"fileType":"image/png","suffix":"png","tmpPath":"/tmp/FUp_2075739431627410001_upload"} * */ String dd = dataMap.get("upload"); System.out.println("------ " + dd); // 获取信息,拼接文件名 JSONObject object = JSON.parseObject(dd); // 路径 String tmpPath = null; Map map = new HashMap(); try { tmpPath = object.get("tmpPath").toString(); } catch (Exception e) { // e.printStackTrace(); return "{\"msg\": \"未查询到文件源路径,请重新上传!\"}"; } // 后缀 String suffix = object.get("suffix").toString(); // 时间戳 long currentTimeMillis = System.currentTimeMillis(); // 时间格式 SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat hmsS = new SimpleDateFormat("HHmmssSSS"); String ymd_str = ymd.format(new Date(currentTimeMillis)); String hmsS_str = hmsS.format(new Date(currentTimeMillis)); /** * 文件另存为路径 * rootPath:根目录 * filePath:文件所在目录(服务器路径) * returnPath:返回给前端的路径 * newPath:文件总目录 * filename:文件名,返回用 */ String rootPath = GlobalData.server_conf_dom4j.getUploaddir(); String filePath = File.separator + "uploads" + File.separator + ymd_str + File.separator + hmsS_str + "." + suffix; String returnPath = "/uploads/" + ymd_str + "/" + hmsS_str + "." + suffix; String newPath = rootPath + filePath; String filename = hmsS_str + "." + suffix; try { // 读取文件、写入文件 File oldFile = new File(tmpPath); File file = new File(newPath); // 判断文件夹是否存在,不存在则创建 if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } FileInputStream in = new FileInputStream(oldFile); FileOutputStream out = new FileOutputStream(file); int fileSize = Integer.parseInt(object.get("fileSize").toString()); byte[] buffer = new byte[fileSize]; if (fileSize > 0) { while ((in.read(buffer)) != -1) { out.write(buffer); } } // 删除缓存旧文件 oldFile.delete(); map.put("uploaded", 1); map.put("url", returnPath); map.put("fileName", filename); return JSON.toJSONString(map); } catch (Exception e) { map.put("uploaded", 0); map.put("error", "{\"number\":201,\"message\":\"上传失败\"}"); map.put("fileName", filename); e.printStackTrace(); } return JSON.toJSONString(map); } /** * 大文件切片上传 * @param hoContext * @return tileset.json */ @ExcludeL public String uploadBigFile(HoContext hoContext) { Map dataMap = hoContext.httpRequest.getParams(); String dd = dataMap.get("file"); // 获取信息,拼接文件名 JSONObject object = JSON.parseObject(dd); // 路径 String tmpPath = null; try { tmpPath = object.get("tmpPath").toString(); } catch (Exception e) { e.printStackTrace(); return "{\"msg\": \"未查询到文件源路径,请重新上传!\"}"; } // 时间戳 long currentTimeMillis = System.currentTimeMillis(); // 时间格式 SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd"); String ymd_str = ymd.format(new Date(currentTimeMillis)); /** * 文件另存为路径 * uuid:存储文件块 * rootPath:根目录 * destDirectory:文件地址 */ String uuid = dataMap.get("uuid"); String rootPath = GlobalData.server_conf_dom4j.getUploaddir(); String uploadPath = File.separator + "uploads" + File.separator + ymd_str; String destDirectory = rootPath + File.separator + "uploads" + File.separator + ymd_str; String targetFilePath = ""; // 读取文件、写入文件 File oldFile = new File(tmpPath); File file = new File(destDirectory); // 判断文件夹是否存在,不存在则创建 if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } file = null; // 文件名称xxx.xxx String fileName = dataMap.get("fileName"); // 压缩包地址、文件uploads下地址 targetFilePath = uploadPath + File.separator + uuid + File.separator + fileName; // 切片id int chunkIndex = Integer.parseInt(dataMap.get("chunkIndex")); // 总切片数 int totalChunks = Integer.parseInt(dataMap.get("totalChunks")); // 切片文件地址 String chunkFileName = rootPath + File.separator + "uploads" + File.separator + uuid + "-" + fileName + ".part" + chunkIndex; File chunkFile = new File(chunkFileName); // try-with-resources 会自动关闭流 try { InputStream inputStream = new FileInputStream(oldFile); FileOutputStream outputStream = new FileOutputStream(chunkFile); chunkFile = null; byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } buffer = null; outputStream.flush(); outputStream.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); } // 创建实例对象 CompdFileUtil compdFileUtil = new CompdFileUtil(); // 删除缓存旧文件,并确保删除成功 try { if (oldFile.exists() && !oldFile.delete()) { System.err.println("警告: 无法删除临时文件 " + tmpPath); } oldFile = null; } catch (Exception e) { System.err.println("删除临时文件异常: " + e.getMessage()); } // 每个分片上传完成后立即调用合并 compdFileUtil.mergeChunks(fileName, chunkIndex, rootPath, uploadPath, uuid); // 检查是否所有切片都已上传 if (chunkIndex == (totalChunks - 1)) { System.gc(); System.out.println("======"+targetFilePath); return "{\"url\": \"" + targetFilePath + "\"}"; } System.gc(); // 手动置空 compdFileUtil = null; return "{\"url\": \"\"}"; } /** * 使用ws长连接解压zip压缩包,根据findname查询路径(不传不查) * @param wsContext {"filepath":"xxx/xxx.zip","findname":""} * @return 返回解压后的文件地址及检索文件地址 */ public void unZipFindFile(WsContext wsContext) { // 获取参数(压缩包地址、检索文件名) Map params = wsContext.datas; String filepath = String.valueOf(params.get("filepath")); String findname = String.valueOf(params.get("findname")); // 定义返回map Map resMap = new HashMap<>(); // 定义upload绝对地址 String rootPath = GlobalData.server_conf_dom4j.getUploaddir(); filepath = rootPath + filepath; // 获取文件所处地址 String parent = Paths.get(filepath).getParent().toString(); // 解析文件名和扩展名 String fileName = Paths.get(filepath).getFileName().toString(); int dotIndex = fileName.lastIndexOf('.'); String nameWithoutExtension = (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName; // String extension = (dotIndex > 0) ? fileName.substring(dotIndex) : ""; // 解压后的文件夹路径 String unzipath = parent + File.separator + nameWithoutExtension; // 创建实例对象 CompdFileUtil compdFileUtil = new CompdFileUtil(); // 解压文件,参数1:压缩包地址,参数2:解压目标目录 compdFileUtil.unzip(filepath, unzipath, new CompdFileUtil.UnzipListener() { @Override public void onProgress(int percentage) { // System.out.println("解压进度: " + percentage + "%"); float per = (float) percentage; SmMessage smMessage = new SmMessage(1, per/100, "解压中..."); smMessage.setProgress(per/100); wsContext.resPrint(JSON.toJSONString(smMessage)); } @Override public void onComplete() { // System.out.println("解压完成"); SmMessage smMessage = new SmMessage(1,1, "解压完成"); smMessage.setProgress(1); wsContext.resPrint(JSON.toJSONString(smMessage)); } @Override public void onError(Exception e) {System.out.println("解压错误: " + e.getMessage());} }); // 若检索文件名不为空则进行检索 if (!findname.equals("") && findname!=null) { // 查找目标文件(如:tileset.json),将根目录进行替换,只返回uploads及后面地址 String findPath = compdFileUtil.findFile(unzipath, findname); if (!StringUtil.isEmpty(findPath)) { // 获取upload位置并进行截取 int upload_index = findPath.indexOf(rootPath); if (upload_index > -1) { findPath = upload_index>-1?findPath.replace(rootPath, ""):""; resMap.put("findPath", findPath); // 存储查找文件路径 } } } System.out.println("======"+unzipath); // 替换掉webroot路径,只返回uploads下地址 resMap.put("filePath", unzipath.indexOf(rootPath)>-1?unzipath.replace(rootPath, ""):"");// 存储解压文件所在路径(uploads后) // 手动置空 compdFileUtil = null; // 解压完成后返回解压文件地址及检索文件 wsContext.resPrint(JSON.toJSONString(resMap)); } }