package com.fdkankan.modeldemo.utils; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fdkankan.modeldemo.bean.SceneEditControlsBean; import com.fdkankan.modeldemo.bean.SceneJsonBean; import com.fdkankan.modeldemo.bean.TagBean; import com.fdkankan.modeldemo.constant.Constant; import com.fdkankan.modeldemo.constant.RedisKey; import com.fdkankan.modeldemo.entity.*; import com.fdkankan.modeldemo.service.*; import com.fdkankan.redis.RedisClient; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; @Slf4j @Component public class ConvertUtil { private static String RESULTS_DIR = "results"; private static String DATA_DIR = "data"; private static String WALLS = "walls"; private static String SUBGROUP = "subgroup"; private static String JSON_EXTNAME = ".json"; private static String IMAGES_4K = "images/4k/"; private static String IMAGES_512 = "images/512/"; private static String IMAGES_8K = "images/8k/"; private static String TITLE = "title"; private final static String SHOOTTIME = "shootTime"; private static String extinguisherJson = "extinguisher.json"; private static String floorplanJsonName = "floorplan.json"; @Autowired private SceneService sceneService; @Autowired private SceneFileMappingService sceneFileMappingService; @Resource private FdfsUtil fdfsUtil; @Resource private RedisClient redisClient; @Autowired private SceneEditInfoService sceneEditInfoService; @Autowired private SceneEditInfoExtService sceneEditInfoExtService; @Autowired private SceneEditControlsService sceneEditControlsService; @Resource private FYunFileService fYunFileService; private static String[] convertVisableHandler(JSONArray visibles, Map uuidMap){ int size = visibles.size(); String[] visibleArr = new String[size]; for(int j = 0; j < size; j++){ int index = (Integer)visibles.get(j); String uuid = uuidMap.get(index); visibleArr[j] = uuid; } return visibleArr; } public static void main(String[] args) throws Exception { String test = "D:\\test\\111.json"; if(FileUtil.exist(test)){ String extinguisherStr = FileUtil.readUtf8String(test); JSONObject jsonObject = JSON.parseObject(extinguisherStr); JSONArray imgBoxsList = jsonObject.getJSONArray("imgBoxsList"); boolean existExtinguisher = imgBoxsList.stream().anyMatch(box -> { JSONObject boxObj = (JSONObject) box; JSONArray shapes = boxObj.getJSONArray("shapes"); return shapes.stream().anyMatch(shape -> { JSONObject shapeObj = (JSONObject) shape; if ("1111".equals(shapeObj.getString("category"))) { return true; } return false; }); }); System.out.println(existExtinguisher); } } public Map convert(String sourcePath, String num, String stationCode, Date upTime, String convertType, String upTimeKey) throws Exception { Map map = new HashMap<>(); String dataViewPath = String.format(Constant.DATA_VIEW_PATH, num); String imgViewPath = String.format(Constant.IMG_VIEW_PATH, num); String obj2TxtPath = null; if(!sourcePath.endsWith(File.separator)){ sourcePath = sourcePath + File.separator; } obj2TxtPath = sourcePath.substring(0, sourcePath.length() - 1) + "_obj2txt"; FileUtil.mkdir(obj2TxtPath); //调用算法生成modeldata.txt String extrasPath = obj2TxtPath + File.separator + "extras"; FileUtil.mkdir(extrasPath); FileUtil.copyContent(new File(sourcePath + DATA_DIR + File.separator + "mesh"), new File(extrasPath), true); //写data.json writeDataJson(obj2TxtPath); //调用算法建模 build3dModel(obj2TxtPath); //校验算法是否正常结束 String uploadJsonPath = obj2TxtPath + File.separator + RESULTS_DIR +File.separator+"upload.json"; boolean success = checkComputeCompleted(uploadJsonPath, 5, 300); if(!success){ throw new RuntimeException("计算失败,obj2TxtPath:" + obj2TxtPath); } String uploadData = FileUtil.readUtf8String(uploadJsonPath); JSONObject uploadJson = null; JSONArray array = null; if(uploadData!=null) { uploadJson = JSONObject.parseObject(uploadData); array = uploadJson.getJSONArray("upload"); } JSONObject fileJson = null; String fileName = ""; for(int i = 0, len = array.size(); i < len; i++) { fileJson = array.getJSONObject(i); fileName = fileJson.getString("file"); //文件不存在抛出异常 if (!new File(obj2TxtPath + File.separator + RESULTS_DIR + File.separator + fileName).exists()) { throw new Exception(obj2TxtPath + File.separator + RESULTS_DIR + File.separator + fileName + "文件不存在"); } //tex文件夹 if (fileJson.getIntValue("clazz") == 15) { // FileUtil.copy(obj2TxtPath + File.separator + RESULTS_DIR + File.separator + fileName, // targetImagePath + File.separator + "tieta_texture/" + fileName.replace("tex/", ""),true); map.put(imgViewPath + "tieta_texture/" + fileName.replace("tex/", ""), obj2TxtPath + File.separator + RESULTS_DIR + File.separator + fileName); } } //压缩成dam String damKey = imgViewPath + "tieta.dam"; String damPath = obj2TxtPath + File.separator + RESULTS_DIR +File.separator + "dam.txt"; CreateObjUtil.convertTxtToDam( obj2TxtPath + File.separator + RESULTS_DIR +File.separator+"modeldata.txt", damPath); map.put(damKey, damPath); //识别灭火器 Integer extinguisher = this.getExtinguisher(num, sourcePath, map); //复制文件 JSONObject standarFloor = null; Integer maxWallNum = 0; if(FileUtil.exist(sourcePath + DATA_DIR + "/" + floorplanJsonName)){ String floorplanJson = FileUtil.readUtf8String(sourcePath + DATA_DIR + "/" + floorplanJsonName); JSONObject jsonObject = JSON.parseObject(floorplanJson); Integer currentId = jsonObject.getInteger("currentId"); if(Objects.nonNull(currentId) && currentId == 0){ FileUtil.del(sourcePath + DATA_DIR + "/" + floorplanJsonName); }else{ JSONArray floors = jsonObject.getJSONArray("floors"); for (Object floor : floors) { JSONObject floorObj = (JSONObject) floor; Map walls = floorObj.getObject(WALLS, Map.class); if(walls.keySet().size() > maxWallNum){ maxWallNum = walls.keySet().size(); standarFloor = floorObj; } } //切割,按subgroup分成多份 for (Object floor : floors) { JSONObject floorObj = (JSONObject) floor; Integer subgroup = floorObj.getIntValue(SUBGROUP); floorObj.put(WALLS, standarFloor.getJSONObject(WALLS)); floorObj.put("points", standarFloor.getJSONObject("points")); floorObj.put(SUBGROUP, 0); floorObj.put("id", 0); jsonObject.replace("floors", Arrays.asList(floorObj)); String floorplanPath = sourcePath + DATA_DIR + "/floorplan" + "-" + subgroup + JSON_EXTNAME; FileUtil.writeUtf8String(jsonObject.toJSONString(), floorplanPath); } } } List dataFiles = FileUtil.loopFiles(sourcePath + DATA_DIR + "/"); for (File dataFile : dataFiles) { if(dataFile.getAbsolutePath().contains("floorplan")){ continue; } map.put(dataFile.getAbsolutePath().replace(sourcePath + DATA_DIR + "/", dataViewPath) , dataFile.getAbsolutePath()); } String finalSourcePath = sourcePath; if(FileUtil.exist(finalSourcePath + IMAGES_4K)){ FileUtil.listFileNames(sourcePath + IMAGES_4K).stream().forEach(v->{ map.put(imgViewPath + "pan/high/" + v.replaceAll("-", ""), finalSourcePath + IMAGES_4K + v); // FileUtil.copy(finalSourcePath + IMAGES_4K + v, targetImagePath + "/pan/high/" + v.replaceAll("-", ""), true); }); } if(FileUtil.exist(finalSourcePath + IMAGES_512)){ FileUtil.listFileNames(finalSourcePath + IMAGES_512).stream().forEach(v->{ map.put(imgViewPath + "pan/low/" + v.replaceAll("-", ""), finalSourcePath + IMAGES_512 + v); // FileUtil.copy(finalSourcePath + IMAGES_512 + v, targetImagePath + "/pan/low/" + v.replaceAll("-", ""), true); }); } if(FileUtil.exist(finalSourcePath + IMAGES_8K)) { FileUtil.listFileNames(finalSourcePath + IMAGES_8K).stream().forEach(v -> { map.put(imgViewPath + "pan/8k/" + v.replaceAll("-", ""), finalSourcePath + IMAGES_8K + v); // FileUtil.copy(finalSourcePath + IMAGES_8K + v, targetImagePath + "/pan/8k/" + v.replaceAll("-", ""), true); }); } // FileUtil.copy(sourcePath + "images/vision.txt", targetImagePath + "/vision.txt", true); //单独上传一份全的vision.txt this.uploadVisionTxt(num, upTimeKey, sourcePath + "images/vision.txt"); //生成vison.modeldata String visionStr = FileUtil.readUtf8String(sourcePath + "images/vision.txt"); JSONObject visionObj = JSON.parseObject(visionStr); JSONArray sweepLocationsArr = visionObj.getJSONArray("sweepLocations"); //分割中高低点位 Map> visibleMap = new HashMap(); Map> subgroupMap = new HashMap<>(); for (Object item : sweepLocationsArr) { JSONObject obj = (JSONObject) item; int subgroup = obj.getIntValue(SUBGROUP); List jsonObjects = subgroupMap.get(subgroup); if(jsonObjects == null){ jsonObjects = new ArrayList<>(); subgroupMap.put(subgroup, jsonObjects); } obj.put(SUBGROUP, 0); jsonObjects.add(obj); List visible = visibleMap.get(subgroup); if(visible == null){ visible = new ArrayList<>(); visibleMap.put(subgroup, visible); } visible.add(obj.getString("uuid")); } for (Integer subgroup : subgroupMap.keySet()) { List jsonObjects = subgroupMap.get(subgroup); List uuidList = visibleMap.get(subgroup); for (JSONObject jsonObject : jsonObjects) { String uuid = jsonObject.getString("uuid"); List list = Lists.newArrayList(uuidList); list.remove(uuid); jsonObject.put("visibles",list); jsonObject.put("visibles2",list); jsonObject.put("visibles3",list); } } //生成场景标题 JSONObject sceneBashInfo = this.getSceneBashInfo(num, sourcePath); //如果是高中低场景,需要上传三份数据 for (Integer subgroup : subgroupMap.keySet()) { //拆分vision.txt String visionTxtPath = sourcePath + "images/vision" + "-" + subgroup + ".txt"; String visionmodeldataPath = sourcePath + "images/visionmodeldata" + "-" + subgroup + ".txt"; JSONObject visionTxtJson = new JSONObject(); visionTxtJson.put("sweepLocations", subgroupMap.get(subgroup)); FileUtil.writeUtf8String(visionTxtJson.toJSONString(), visionTxtPath); CreateObjUtil.convertTxtToVisionmodeldata(visionTxtPath, visionmodeldataPath); map.put(imgViewPath + "vision.modeldata", visionmodeldataPath); map.put(imgViewPath + "vision.txt", visionTxtPath); //拆分floorplan.json String floorplanPath = sourcePath + DATA_DIR + "/floorplan" + "-" + subgroup + JSON_EXTNAME; if(FileUtil.exist(floorplanPath)){ map.put(dataViewPath + "floorplan.json", floorplanPath); } //生成scene.json String sceneJsonPath = sourcePath + DATA_DIR + "/scene" + "-" + subgroup + JSON_EXTNAME; SceneJsonBean sceneJsonBean = this.genSceneJson(num, sceneBashInfo.getString(TITLE), subgroup); FileUtil.writeUtf8String(JSON.toJSONString(sceneJsonBean), sceneJsonPath); map.put(dataViewPath + "scene.json", sceneJsonPath); String finalRoomId = num; map.keySet().stream().forEach(key->{ List sceneFileMappingList = sceneFileMappingService.getByScene(finalRoomId, subgroup, upTimeKey, key); if(CollUtil.isNotEmpty(sceneFileMappingList)){ List deleteIds = sceneFileMappingList.stream().map(v -> v.getId()).collect(Collectors.toList()); sceneFileMappingService.removeByIds(deleteIds); } SceneFileMapping sceneFileMapping = new SceneFileMapping(); Map mapping = fdfsUtil.uploadFile(map.get(key)); sceneFileMapping.setNum(finalRoomId); sceneFileMapping.setFileid(mapping.get("file_id")); sceneFileMapping.setUrl(mapping.get("http_url")); sceneFileMapping.setKey(key); sceneFileMapping.setSubgroup(subgroup); sceneFileMapping.setUpTime(upTimeKey); sceneFileMappingService.save(sceneFileMapping); }); // List list = sceneService.list(new LambdaQueryWrapper().eq(Scene::getNum, num).eq(Scene::getSubgroup, subgroup).eq(Scene::getUpTimeKey, upTimeKey)); // Scene scene = null; // if(CollUtil.isEmpty(list)){ // scene = new Scene(); // }else{ // if(list.size() > 1){ // sceneService.remove(new LambdaQueryWrapper().eq(Scene::getNum, num)); // scene = new Scene(); // }else{ // scene = list.get(0); // } // } Scene scene = new Scene(); scene.setTitle(sceneBashInfo.getString(TITLE)); scene.setNum(num); scene.setFloorlogosize(100); scene.setScenekind("pano"); scene.setSceneresolution("4k"); scene.setScenefrom("realsee"); scene.setModelkind("dam"); scene.setFloorplanangle(0); scene.setSubgroup(subgroup); scene.setStationcode(stationCode); scene.setShootTime(sceneBashInfo.getDate(SHOOTTIME)); scene.setUpTime(upTime); scene.setAlgorithmTime(new Date()); scene.setExtinguisher(extinguisher); scene.setUpTimeKey(upTimeKey); scene.setCacheKeyHasTime(1); sceneService.save(scene); SceneEditInfo sceneEditInfo = new SceneEditInfo(); sceneEditInfo.setScenePlusId(scene.getId()); sceneEditInfo.setTitle(scene.getTitle()); sceneEditInfo.setDescription(scene.getDescription()); sceneEditInfoService.save(sceneEditInfo); SceneEditInfoExt sceneEditInfoExt = new SceneEditInfoExt(); sceneEditInfoExt.setScenePlusId(scene.getId()); sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId()); sceneEditInfoExtService.save(sceneEditInfoExt); SceneEditControls sceneEditControls = new SceneEditControls(); sceneEditControls.setEditInfoId(sceneEditInfo.getId()); sceneEditControlsService.save(sceneEditControls); //同步热点 this.keepHot(scene, sceneEditInfo); } return map; } private void keepHot(Scene scene, SceneEditInfo sceneEditInfo){ String num = scene.getNum(); String upTimeKey = scene.getUpTimeKey(); Integer subgroup = scene.getSubgroup(); //查询最新的历史场景 Scene preScene = sceneService.getOne(new LambdaQueryWrapper() .eq(Scene::getNum, num) .eq(Scene::getSubgroup, subgroup) .lt(Scene::getUpTimeKey, upTimeKey) .orderByDesc(Scene::getUpTimeKey).last("limit 1")); if(Objects.isNull(preScene)){ return; } //查询是否有热点 String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup, preScene.getUpTimeKey(), preScene.getCacheKeyHasTime())); Map allTagsMap = redisClient.hmget(RedisClient.scene_sys_code, key); if(CollUtil.isEmpty(allTagsMap)){ return; } //如果有热点,复制redis和涉及的图片 String newKey = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup, upTimeKey, scene.getCacheKeyHasTime())); redisClient.hmset(RedisClient.scene_sys_code, newKey, allTagsMap); sceneEditInfo.setTags(1); sceneEditInfoService.updateById(sceneEditInfo); //组装热点数据 for (String sid : allTagsMap.keySet()) { String hot = allTagsMap.get(sid); JSONObject jsonObject = JSON.parseObject(hot); String type = jsonObject.getString("type"); if(!"image".equals(type) && !"video".equals(type) && !"audio".equals(type)){ continue; } JSONObject media = jsonObject.getJSONObject("media"); JSONArray mediaDetail = media.getJSONArray(type); List keyList = mediaDetail.stream().map(v -> { JSONObject content = (JSONObject) v; String src = content.getString("src"); return String.format(Constant.USER_VIEW_PATH, num) + src; }).collect(Collectors.toList()); if(CollUtil.isNotEmpty(keyList)){ List fileMappingList = sceneFileMappingService.getBySceneBatch(num, subgroup, preScene.getUpTimeKey(), keyList); if(CollUtil.isNotEmpty(fileMappingList)){ fileMappingList.stream().forEach(v->{ v.setId(null); v.setUpTime(upTimeKey); }); sceneFileMappingService.saveBatch(fileMappingList); } } } //发布热点 this.publicHotData(scene); //复制icon //查询缓存是否包含icons String iconKey = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup, preScene.getUpTimeKey() ,preScene.getCacheKeyHasTime())); Set icons = redisClient.sGet(RedisClient.scene_sys_code, iconKey); if(CollUtil.isNotEmpty(icons)){ String newIconKey = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup, scene.getUpTimeKey() ,scene.getCacheKeyHasTime())); redisClient.sSet(RedisClient.scene_sys_code, newIconKey, icons); List iconFileList = icons.stream().map(i -> { return String.format(Constant.USER_VIEW_PATH, num) + i; }).collect(Collectors.toList()); if(CollUtil.isNotEmpty(iconFileList)){ List fileMappingList = sceneFileMappingService.getBySceneBatch(num, subgroup, preScene.getUpTimeKey(), iconFileList); if(CollUtil.isNotEmpty(fileMappingList)){ fileMappingList.stream().forEach(v->{ v.setId(null); v.setUpTime(scene.getUpTimeKey()); }); sceneFileMappingService.saveBatch(fileMappingList); } } } } private void publicHotData(Scene scene) { String sceneNum = scene.getNum(); Integer subgroup = scene.getSubgroup(); String upTime = scene.getUpTimeKey(); Integer cacheKeyHasTime = scene.getCacheKeyHasTime(); String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(sceneNum, subgroup,upTime,cacheKeyHasTime)); Map hotMap = redisClient.hmget(RedisClient.scene_sys_code, hotDataKey); JSONArray tags = new JSONArray(); if(CollUtil.isNotEmpty(hotMap)){ List tagBeanList = hotMap.entrySet().stream().map(entry -> { JSONObject jsonObject = JSON.parseObject(entry.getValue()); return TagBean.builder() .createTime(jsonObject.getLong("createTime")) .tag(jsonObject).build(); }).collect(Collectors.toList()); //按创建时间倒叙排序 tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed()); //移除createTime字段 tagBeanList.stream().forEach(tagBean -> { tags.add(tagBean.getTag()); }); } String hotJsonPath = String.format(Constant.USER_VIEW_PATH, sceneNum) + "hot.json"; fYunFileService.uploadFile(sceneNum, subgroup, upTime, tags.toString().getBytes(StandardCharsets.UTF_8), hotJsonPath); } private Integer getExtinguisher(String num, String sourcePath, Map map){ int extinguisher = 0; try { String imgViewPath = String.format(Constant.IMG_VIEW_PATH, num); //灭火器标注识别 String imagesPath = sourcePath + "images/"; String annihilatorPath = imagesPath + "4k/"; String cmd = "bash /home/ubuntu/bin/PotreeConverter.sh tieta_det " + annihilatorPath + " /home/ubuntu/bin/model/best.onnx " + imagesPath + extinguisherJson; log.info("---------start extinguisher, cmd:{}", cmd); CmdUtils.callLineSh(cmd); log.info("---------end extinguisher, cmd:{}", cmd); if(FileUtil.exist(imagesPath + extinguisherJson)){ map.put(imgViewPath + extinguisherJson, imagesPath + extinguisherJson); String extinguisherStr = FileUtil.readUtf8String(imagesPath + extinguisherJson); JSONObject jsonObject = JSON.parseObject(extinguisherStr); JSONArray imgBoxsList = jsonObject.getJSONArray("imgBoxsList"); boolean existExtinguisher = imgBoxsList.stream().anyMatch(box -> { JSONObject boxObj = (JSONObject) box; JSONArray shapes = boxObj.getJSONArray("shapes"); if(CollUtil.isNotEmpty(shapes)){ return shapes.stream().anyMatch(shape -> { JSONObject shapeObj = (JSONObject) shape; if ("extinguisher".equals(shapeObj.getString("category"))) { return true; } return false; }); } return false; }); if(existExtinguisher){ extinguisher = 1; } } }catch (Exception e){ log.error("getExtinguisher fail, num:{}", num, e); } return extinguisher; } private void uploadVisionTxt(String num, String upTime, String localVisionTxtPath){ String key = String.format(Constant.IMG_VIEW_PATH, num) + "vision.txt"; List sceneFileMappingList = sceneFileMappingService.getByScene(num, -1, upTime, key); if(CollUtil.isNotEmpty(sceneFileMappingList)){ List deleteIds = sceneFileMappingList.stream().map(v -> v.getId()).collect(Collectors.toList()); sceneFileMappingService.removeByIds(deleteIds); } SceneFileMapping sceneFileMapping = new SceneFileMapping(); Map mapping = fdfsUtil.uploadFile(localVisionTxtPath);//sourcePath + "images/vision.txt" sceneFileMapping.setNum(num); sceneFileMapping.setFileid(mapping.get("file_id")); sceneFileMapping.setUrl(mapping.get("http_url")); sceneFileMapping.setKey(key); sceneFileMapping.setSubgroup(-1); sceneFileMapping.setUpTime(upTime); sceneFileMappingService.save(sceneFileMapping); } private SceneJsonBean genSceneJson(String roomId, String title, Integer subgroup){ SceneEditControlsBean sceneEditControlsBean = SceneEditControlsBean.builder() .showDollhouse(1).showMap(1).showPanorama(1).showVR(1).showTitle(1).showFloorplan(1).build(); SceneJsonBean sceneJsonBean = SceneJsonBean.builder() .title(title).description(null) .num(roomId).subgroup(subgroup).floorLogoSize(100).sceneKind("pano") .sceneResolution("4k").sceneFrom("realsee") .modelKind("dam").floorPlanAngle(0).controls(sceneEditControlsBean).build(); return sceneJsonBean; } private JSONObject getSceneBashInfo(String roomId, String sourcePath){ JSONObject info = new JSONObject(); String sceneJsonPath = sourcePath + DATA_DIR + "/scene.json"; if(!FileUtil.exist(sceneJsonPath)){ return info; } String sceneJsonStr = FileUtil.readUtf8String(sceneJsonPath); JSONObject jsonObject = JSON.parseObject(sceneJsonStr); String title = jsonObject.getString(TITLE); if(StrUtil.isEmpty(title)){ title = roomId; } info.put(TITLE, title); String shootTimeStr = jsonObject.getString(SHOOTTIME); if(StrUtil.isNotEmpty(shootTimeStr)){ info.put(SHOOTTIME, DateUtil.parse(shootTimeStr, DatePattern.NORM_DATETIME_FORMAT)); } return info; } public static void writeDataJson(String path){ JSONObject dataJson = new JSONObject(); dataJson.put("obj2txt", true); dataJson.put("split_type", "SPLIT_V6"); dataJson.put("data_describe", "double spherical"); dataJson.put("skybox_type", "SKYBOX_V5"); FileUtil.writeUtf8String(dataJson.toString(), path + File.separator + "data.json"); } public static void build3dModel(String folderName) throws Exception { System.out.println("开始建模"); String command = "sudo bash /home/ubuntu/bin/Launcher.sh " + folderName; CmdUtils.callLineSh(command); System.out.println("计算完毕:" + command); } public static boolean checkComputeCompleted(String uploadJsonPath, int maxCheckTimes, long waitTime) throws Exception { int checkTimes = 1; boolean exist = false; do { if ((new File(uploadJsonPath)).exists()) { exist = true; break; } Thread.sleep(waitTime); ++checkTimes; } while(checkTimes <= maxCheckTimes); return exist; } }