1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
| * 情景教学压缩操作类 */ public class CompressHandler extends Thread { private Logger logger = Logger.getLogger(CompressHandler.class); /** * 存储目录名和对应目录下的文件地址 */ private Map<String, List<ResourceInfo>> resourceMap; /** * 压缩类中的配置文件 */ private String configJson; /** * 配置文件map key为压缩包中的文件名,value为文件内容 */ Map<String, String> configJsonMap; /** * 回调接口 */ private ZipOperate zipOperate; /** * 加密标志 */ private boolean encrypt = false; /** * 线程名称 */ private String threadName = Thread.currentThread().getName(); /** * 取消标志 */ private boolean cancelFlag; public CompressHandler() { } public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, Map<String, String> configJsonMap, ZipOperate zipOperate) { this(resourceMap, configJsonMap, zipOperate, false); } public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, Map<String, String> configJsonMap, ZipOperate zipOperate, boolean encrypt) { this.resourceMap = resourceMap; this.configJsonMap = configJsonMap; this.zipOperate = zipOperate; this.encrypt = encrypt; } public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, String configJson, ZipOperate zipOperate) { this(resourceMap, configJson, zipOperate, false); } public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, String configJson, ZipOperate zipOperate, boolean encrypt) { this.resourceMap = resourceMap; this.configJson = configJson; this.zipOperate = zipOperate; this.encrypt = encrypt; } @Override public void run() { if (zipOperate != null) { zipOperate.beforeCompress(); } String fileName = UUID.randomUUID().toString().replace("-", "").concat(".zip"); String tempDir = SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_TMMP_FILE_PATH); File tempDirFile = new File(tempDir); if (!tempDirFile.exists()) { tempDirFile.mkdir(); } String filePath = tempDir.concat("/").concat(fileName); //存储生成本地压缩包的文件 List<File> encryptFileList = new ArrayList<>(); try { ZipFile zipFile = new ZipFile(filePath); logger.info("线程" + threadName + " 开始压缩,压缩的文件名为:" + fileName); long startTime = System.currentTimeMillis(); logger.info("线程" + threadName + " 开始时间为:" + startTime); ZipParameters parameters = new ZipParameters(); //设置压缩方式和压缩级别 parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); //当开启压缩包密码加密时 boolean dirEncrypt = false; if (encrypt || Boolean.parseBoolean(SuperdiamondConfig.getConfig(SuperdiamondConfig.ENABLE_ENCRYPT_ZIP))) { logger.info("线程" + threadName + " 该压缩包需要加密"); addEncryptParameters(parameters); dirEncrypt = true; } for (String dir : resourceMap.keySet()) { logger.info("线程" + threadName + " 添加目录:" + dir); List<ResourceInfo> resourceInfoList = resourceMap.get(dir); for (ResourceInfo resourceInfo : resourceInfoList) { String resourceFileName = resourceInfo.getFileName(); logger.info("线程" + threadName + " 添加文件:" + resourceFileName); /** * 20180921判断目录名是否为空字符串 true不创建目录 by lizhang10 */ if(StringUtils.isNotEmpty(dir)){ parameters.setFileNameInZip(dir + "/" + resourceFileName); }else{ parameters.setFileNameInZip(resourceFileName); } parameters.setSourceExternalStream(true); InputStream inputStream = resourceInfo.getInputStream(); if (inputStream == null) { //获取文件流 String fileUrl = resourceInfo.getFileUrl(); long startTime1 = System.currentTimeMillis(); logger.info("线程" + threadName + " 开始获取文件流,地址:" + fileUrl + " 开始时间:" + startTime1); inputStream = getInputStream(fileUrl); long endTime1 = System.currentTimeMillis(); logger.info("线程" + threadName + " 结束获取文件流,地址:" + fileUrl + " 结束时间:" + endTime1 + " 耗时毫秒: " + (endTime1 - startTime1)); } //当压缩包没有加密时,则从文件属性中取是否进行加密 if(!dirEncrypt && resourceInfo.isEncrypt()){ //如果是zip的话,则对文件进行解压,然后再加密 if(resourceFileName.endsWith(".zip")){ long saveStartTime = System.currentTimeMillis(); //网络文件路径 String sourceFileName = tempDir.concat("/").concat(UUID.randomUUID().toString().concat(".zip")); logger.info("线程" + threadName + " 该文件["+resourceFileName+"]是zip且需要加密,开始存到本地,路径为:"+sourceFileName+"开始时间:" + saveStartTime); //加密文件路径 String encryptFileName = tempDir.concat("/").concat(UUID.randomUUID().toString().concat(".zip")); File file = new File(sourceFileName); FileOutputStream outputStream = new FileOutputStream(file); byte[] buffer = new byte[8*1024]; int len = 0; while ((len = inputStream.read(buffer)) != -1){ outputStream.write(buffer,0,len); } outputStream.close(); inputStream.close(); long saveEndTime = System.currentTimeMillis(); logger.info("线程" + threadName + " 该文件是zip,存到本地完成,结束时间:" + saveEndTime + " 耗时:"+(saveEndTime - saveStartTime)); long extractStartTime = System.currentTimeMillis(); logger.info("线程" + threadName + " ,开始进行解压加密,开始时间为:" + extractStartTime); ZipFile sourceZipFile = new ZipFile(file); String extractDir = tempDir.concat("/").concat(UUID.randomUUID().toString()); sourceZipFile.extractAll(extractDir); long extractEndTime = System.currentTimeMillis(); ZipFile encryptZipFile = new ZipFile(encryptFileName); ZipParameters parameters2 = new ZipParameters(); //设置压缩方式和压缩级别 parameters2.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters2.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); addEncryptParameters(parameters2); //添加获取文件的文件和目录 File[] fileArray = new File(extractDir).listFiles(); for (File file1 : fileArray) { if(file1.isDirectory()){ encryptZipFile.addFolder(file1,parameters2); } else { encryptZipFile.addFile(file1,parameters2); } } if(!StringUtils.isEmpty(resourceInfo.getConfigJson())){ parameters2.setFileNameInZip("config.json"); parameters2.setSourceExternalStream(true); encryptZipFile.addStream(new ByteArrayInputStream(resourceInfo.getConfigJson().getBytes("utf8")),parameters2); } logger.info("线程" + threadName + " ,完成解压加密,结束时间为:" + extractEndTime + " 耗时: " + (extractEndTime-extractStartTime)); //删除文件 sourceZipFile.getFile().delete(); //删除目录下的文件 deleteFolder(new File(extractDir)); File encryptFile = encryptZipFile.getFile(); inputStream = new FileInputStream(encryptFile); encryptFileList.add(encryptFile); } } //获取需要打包的文件流 zipFile.addStream(inputStream, parameters); inputStream.close(); } } parameters.setSourceExternalStream(true); //如果configJsonMap不为空,且length不为0,则遍历加入到压缩包中 if (configJsonMap != null && configJsonMap.size() > 0) { for (String resourceName : configJsonMap.keySet()) { logger.info("线程" + threadName + " 添加配置文件" + resourceName); parameters.setFileNameInZip(resourceName); String value = configJsonMap.get(resourceName); zipFile.addStream(new ByteArrayInputStream(value.getBytes("utf8")), parameters); } } if (!StringUtils.isEmpty(configJson)) { logger.info("线程" + threadName + " 添加文件config.json"); parameters.setFileNameInZip("config.json"); zipFile.addStream(new ByteArrayInputStream(configJson.getBytes("utf8")), parameters); } logger.info("线程" + threadName + " 压缩文件" + fileName + "完成"); long endTime = System.currentTimeMillis(); logger.info("线程" + threadName + " 结束时间为:" + endTime + " 耗时毫秒:" + (endTime - startTime)); long startTime2 = System.currentTimeMillis(); logger.info("线程" + threadName + " 开始将压缩包上传到文件服务.......开始时间:" + startTime2); FileInfo fileInfo = new CystrageUtil().uploadToRemoteServer(fileName, filePath, null); long endTime2 = System.currentTimeMillis(); logger.info("线程" + threadName + " 上传完成.......结束时间:" + endTime2 + "耗时毫秒: " + (endTime2 - startTime2)); if (cancelFlag){ throw new InterruptedException("线程" + threadName + " 取消压缩"); } //如果传入了后续操作接口,则将文件服务返回的类传入 if (zipOperate != null) { zipOperate.afterCompress(fileInfo, zipFile); zipFile.getFile().delete(); } } catch (Exception e) { logger.error("线程" + threadName + " 文件压缩出错...........文件内容:" + configJson, e); if (zipOperate != null) { zipOperate.errorCompress(); } //删除对应压缩包 new File(filePath).delete(); } finally { try { //关流 inputStream.close(); } catch (IOException e) { inputStream = null; } //删除本地生成的压缩文件 //存储生成本地压缩包的文件 for (File file : encryptFileList) { file.delete(); } } } /** * 删除文件夹下的所有文件 * @param sourceDir */ private void deleteFolder(File sourceDir) { if(sourceDir.isDirectory()){ File[] files = sourceDir.listFiles(); for (File file : files) { deleteFolder(file); } } else { sourceDir.delete(); } sourceDir.delete(); } private void addEncryptParameters(ZipParameters parameters) { String password = SuperdiamondConfig.getConfig(SuperdiamondConfig.ZIP_COMPRESS_PASSWORD); parameters.setEncryptFiles(true); parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); parameters.setPassword(password.toCharArray()); } /** * 获取输入流 * * @param fileUrl * @return */ InputStream inputStream; private InputStream getInputStream(String fileUrl) throws Exception { if(cancelFlag){ throw new InterruptedException("线程" + threadName + " 取消压缩"); } int retry = 1; while (retry <= 3) { try { int index = fileUrl.lastIndexOf("/"); String prefix = fileUrl.substring(0, index + 1); String fileName = fileUrl.substring(index + 1); URL url = new URL(prefix + URLEncoder.encode(fileName, "utf8")); URLConnection connection = url.openConnection(); connection.setDoInput(true); inputStream = connection.getInputStream(); return inputStream; } catch (Exception e) { if (retry == 1) { logger.error("线程" + threadName + " 获取文件出错,文件地址:" + fileUrl, e); } logger.error("开始重试第" + retry + "次"); //由于测试环境服务器承载能力比较差,当获取失败后,睡眠一段时间再重试 if(Boolean.parseBoolean(SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_TEST_ENVIRONMENT))){ Thread.currentThread().sleep(Long.parseLong(SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_SLEEP_TIME))); } if (retry == 3) { throw new Exception(e); } retry++; } } return null; } public void setCancelFlag(Boolean cancelFlag){ this.cancelFlag = cancelFlag; } @Override public void interrupt() { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { inputStream = null; logger.info("线程" + threadName + " 关闭io流失败"); } } super.interrupt(); } public static class ResourceInfo { /** * 文件名称 */ private String fileName; /** * 文件地址 */ private String fileUrl; /** * 输入流 */ private InputStream inputStream; /** * 是否要为当前文件添加config,json */ private String configJson; /** * 改文件是否加密 */ private boolean encrypt; public InputStream getInputStream() { return inputStream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFileUrl() { return fileUrl; } public void setFileUrl(String fileUrl) { this.fileUrl = fileUrl; } public boolean isEncrypt() { return encrypt; } public void setEncrypt(boolean encrypt) { this.encrypt = encrypt; } public String getConfigJson() { return configJson; } public void setConfigJson(String configJson) { this.configJson = configJson; } } }
|