|
@@ -0,0 +1,351 @@
|
|
|
+package com.shkpr.service.alambizplugin.components;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.global.base.log.LogLevelFlag;
|
|
|
+import com.global.base.log.LogPrintMgr;
|
|
|
+import com.shkpr.service.alambizplugin.commproperties.AsyncTaskProperties;
|
|
|
+import com.shkpr.service.alambizplugin.commproperties.TempFileProperties;
|
|
|
+import com.shkpr.service.alambizplugin.commtools.CompressorUtils;
|
|
|
+import com.shkpr.service.alambizplugin.commtools.ExcelUtils;
|
|
|
+import com.shkpr.service.alambizplugin.commtools.ShapeUtils;
|
|
|
+import com.shkpr.service.alambizplugin.constants.ExcelEnum;
|
|
|
+import com.shkpr.service.alambizplugin.constants.GisSurveyExcelDefine;
|
|
|
+import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
|
|
|
+import org.apache.commons.compress.archivers.ArchiveException;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
+import org.opengis.feature.simple.SimpleFeatureType;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.ByteBuffer;
|
|
|
+import java.nio.channels.FileChannel;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 异步结果管理器
|
|
|
+ *
|
|
|
+ * @author 欧阳劲驰
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class AsyncResultManager {
|
|
|
+ /**
|
|
|
+ * 结果文件名
|
|
|
+ */
|
|
|
+ public final static String RESULT_FILE_NAME = "result.json";
|
|
|
+ /**
|
|
|
+ * 临时文件夹缓存
|
|
|
+ */
|
|
|
+ private final static Map<String, Path> TEMP_DIR_CACHE = new ConcurrentHashMap<>();
|
|
|
+ /**
|
|
|
+ * 文件分片大小
|
|
|
+ */
|
|
|
+ private final static Integer BUFFER_SIZE = 4 * 1024;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * log
|
|
|
+ */
|
|
|
+ private final String mStrClassName;
|
|
|
+ private final String mBizType;
|
|
|
+ private final AsyncTaskProperties asyncTaskProperties;
|
|
|
+ private final TempFileProperties tempFileProperties;
|
|
|
+ private final ObjectMapper objectMapper;
|
|
|
+
|
|
|
+ public AsyncResultManager(AsyncTaskProperties asyncTaskProperties, TempFileProperties tempFileProperties, ObjectMapper objectMapper) {
|
|
|
+ mStrClassName = "AsyncResultManager";
|
|
|
+ mBizType = LogFlagBusiType.BUSI_GIS_SURVEY.toStrValue();
|
|
|
+ this.asyncTaskProperties = asyncTaskProperties;
|
|
|
+ this.tempFileProperties = tempFileProperties;
|
|
|
+ this.objectMapper = objectMapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取结果
|
|
|
+ *
|
|
|
+ * @param flag 结果标识
|
|
|
+ * @return 检查结果
|
|
|
+ */
|
|
|
+ public <T> T getResult(String flag, TypeReference<T> type) {
|
|
|
+ //创建文件输入流
|
|
|
+ File file = Paths.get(getResultDirPath(flag).toString(), RESULT_FILE_NAME).toFile();
|
|
|
+ if (!file.exists()) return null;
|
|
|
+ try (FileInputStream fileInputStream = new FileInputStream(file)) {
|
|
|
+ //获取文件通道
|
|
|
+ FileChannel channel = fileInputStream.getChannel();
|
|
|
+ //创建缓冲区
|
|
|
+ ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
|
|
|
+ //读取通道
|
|
|
+ int read = channel.read(byteBuffer);
|
|
|
+ //输入读取信息
|
|
|
+ if (read > 0) return objectMapper.readValue(byteBuffer.array(), type);
|
|
|
+ } catch (IOException e) {
|
|
|
+ //打印报错信息
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "监测到io异常 结果标识:%s error:%s"
|
|
|
+ , flag
|
|
|
+ , e
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取结果文件夹路径
|
|
|
+ *
|
|
|
+ * @param flag 结果标识
|
|
|
+ * @return 结果文件夹路径
|
|
|
+ */
|
|
|
+ private Path getResultDirPath(String flag) {
|
|
|
+ return Paths.get(asyncTaskProperties.getResultPath().toString(), flag);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建临时文件夹
|
|
|
+ *
|
|
|
+ * @param flag 结果标识
|
|
|
+ */
|
|
|
+ public Boolean createTempDirectory(String flag) {
|
|
|
+ try {
|
|
|
+ //创建临时文件夹,并缓存路径
|
|
|
+ Path tempDirectory = Files.createTempDirectory(tempFileProperties.getResourcePath(), flag);
|
|
|
+ TEMP_DIR_CACHE.put(flag, tempDirectory);
|
|
|
+ return tempDirectory.toFile().exists();
|
|
|
+ } catch (IOException e) {
|
|
|
+ //打印报错信息
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "监测到io异常 结果标识:%s error:%s"
|
|
|
+ , flag
|
|
|
+ , e
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 写入json文件
|
|
|
+ *
|
|
|
+ * @param data 数据
|
|
|
+ * @param flag 结果标识
|
|
|
+ * @param fileName 文件名
|
|
|
+ */
|
|
|
+ public Path writeJson(Object data, String flag, String fileName) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "开始执行写入结果文件,结果标识:%s,文件名:%s========>"
|
|
|
+ , flag
|
|
|
+ , fileName
|
|
|
+ )
|
|
|
+ );
|
|
|
+ long begin = System.currentTimeMillis();
|
|
|
+
|
|
|
+ //写入文件
|
|
|
+ Path path = Paths.get(TEMP_DIR_CACHE.get(flag).toString(), fileName);
|
|
|
+ try {
|
|
|
+ //序列化数据
|
|
|
+ final byte[] bytes = objectMapper.writeValueAsBytes(data);
|
|
|
+ //写入文件
|
|
|
+ int total = writeFile(bytes, path);
|
|
|
+ if (total > 0) {
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "结束执行写入结果文件,结果标识:%s,文件名:%s,用时(毫秒):%d"
|
|
|
+ , flag
|
|
|
+ , fileName
|
|
|
+ , (end - begin)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return path;
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ //打印报错信息
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "监测到io异常 结果标识:%s error:%s"
|
|
|
+ , flag
|
|
|
+ , e
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 写入excel文件
|
|
|
+ *
|
|
|
+ * @param heads 表头
|
|
|
+ * @param datas 数据
|
|
|
+ * @param flag 结果标识
|
|
|
+ * @param fileName 文件名
|
|
|
+ */
|
|
|
+ public Path writeExcel(Map<String, Map<String, String>> heads, Map<String, List<Map<String, Object>>> datas, String flag, String fileName) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "开始执行写入excel文件,结果标识:%s,文件名:%s========>"
|
|
|
+ , flag
|
|
|
+ , fileName
|
|
|
+ )
|
|
|
+ );
|
|
|
+ long begin = System.currentTimeMillis();
|
|
|
+
|
|
|
+ //写入文件
|
|
|
+ Path path = Paths.get(TEMP_DIR_CACHE.get(flag).toString(), fileName);
|
|
|
+ try {
|
|
|
+ ExcelUtils.writeFile(heads, datas, Files.newOutputStream(path), ExcelEnum.XLSX
|
|
|
+ , GisSurveyExcelDefine.FILE_HANDLE.HEADER_ROW_NUM, GisSurveyExcelDefine.FILE_HANDLE.DATA_ROW_NUM);
|
|
|
+
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "结束执行写入excel文件,结果标识:%s,文件名:%s,用时(毫秒):%d"
|
|
|
+ , flag
|
|
|
+ , fileName
|
|
|
+ , (end - begin)
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ return path;
|
|
|
+ } catch (IOException e) {
|
|
|
+ //打印报错信息
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "监测到io异常 结果标识:%s error:%s"
|
|
|
+ , flag
|
|
|
+ , e
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 写入shape文件
|
|
|
+ *
|
|
|
+ * @param data 数据
|
|
|
+ * @param flag 结果标识
|
|
|
+ * @param fileName 文件名
|
|
|
+ */
|
|
|
+ public Path writeShape(Map<SimpleFeatureType, List<Map<String, Object>>> data, String flag, String fileName) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "开始执行写入shape文件,结果标识:%s,文件名:%s========>"
|
|
|
+ , flag
|
|
|
+ , fileName
|
|
|
+ )
|
|
|
+ );
|
|
|
+ long begin = System.currentTimeMillis();
|
|
|
+
|
|
|
+ //写入文件
|
|
|
+ Path path = Paths.get(TEMP_DIR_CACHE.get(flag).toString(), fileName);
|
|
|
+ try {
|
|
|
+ //创建临时文件夹
|
|
|
+ Path tempDirectory = Files.createTempDirectory(tempFileProperties.getResourcePath(), flag);
|
|
|
+ //导出到shape
|
|
|
+ ShapeUtils.writeShape(data, tempDirectory);
|
|
|
+ //压缩文件夹
|
|
|
+ Path zipPath = CompressorUtils.archivalZip(tempDirectory);
|
|
|
+ //移动文件
|
|
|
+ FileUtils.moveFile(zipPath.toFile(), path.toFile());
|
|
|
+
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "结束执行写入shape文件,结果标识:%s,文件名:%s,用时(毫秒):%d"
|
|
|
+ , flag
|
|
|
+ , fileName
|
|
|
+ , (end - begin)
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ return path;
|
|
|
+ } catch (IOException | ArchiveException e) {
|
|
|
+ //打印报错信息
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "监测到io异常 结果标识:%s error:%s"
|
|
|
+ , flag
|
|
|
+ , e
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 写文件
|
|
|
+ *
|
|
|
+ * @param data 数据
|
|
|
+ * @param path 文件路径
|
|
|
+ * @return 写入数量
|
|
|
+ * @throws IOException io异常
|
|
|
+ */
|
|
|
+ private int writeFile(final byte[] data, final Path path) throws IOException {
|
|
|
+ //创建文件输出流(此处会创建文件)
|
|
|
+ try (FileOutputStream fileOutputStream = new FileOutputStream(path.toFile())) {
|
|
|
+ //获取文件通道
|
|
|
+ FileChannel channel = fileOutputStream.getChannel();
|
|
|
+ //创建缓冲区
|
|
|
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
|
|
|
+ //偏移量
|
|
|
+ int offset = 0;
|
|
|
+ //写入总数
|
|
|
+ int total = 0;
|
|
|
+ while (offset < data.length) {
|
|
|
+ //分片大小
|
|
|
+ int chunkSize = Math.min(BUFFER_SIZE, data.length - offset);
|
|
|
+ //重置缓冲区,存入缓冲区,翻转
|
|
|
+ byteBuffer.clear();
|
|
|
+ byteBuffer.put(data, offset, chunkSize);
|
|
|
+ byteBuffer.flip();
|
|
|
+ //写入当前块
|
|
|
+ total += channel.write(byteBuffer);
|
|
|
+ offset += chunkSize;
|
|
|
+ }
|
|
|
+ //强制写入
|
|
|
+ channel.force(true);
|
|
|
+ return total;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 替换结果
|
|
|
+ *
|
|
|
+ * @param flag 结果标识
|
|
|
+ * @return 替换状态
|
|
|
+ */
|
|
|
+ public boolean replaceResult(String flag) {
|
|
|
+ //临时文件路径
|
|
|
+ Path path = TEMP_DIR_CACHE.get(flag);
|
|
|
+ try {
|
|
|
+ //替换结果目录
|
|
|
+ FileUtils.copyDirectory(path.toFile(), getResultDirPath(flag).toFile());
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (IOException e) {
|
|
|
+ //打印报错信息
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format(
|
|
|
+ "监测到io异常 结果标识:%s error:%s"
|
|
|
+ , flag
|
|
|
+ , e
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|