CloudFileParsing.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. package com.cpp.web.service.cloud;
  2. import com.cpp.common.utils.StringUtils;
  3. import com.cpp.web.domain.cloud.ForecastPowerShortTermCloud;
  4. import com.cpp.web.domain.cloud.NwpCloud;
  5. import com.cpp.web.domain.datafactory.ParsingLog;
  6. import com.cpp.web.domain.datafactory.enums.FileTypeEnum;
  7. import com.cpp.web.domain.enums.AlarmEnum;
  8. import com.cpp.web.domain.enums.DataSourcesEnum;
  9. import com.cpp.web.service.alarm.AbnormalAlarmService;
  10. import com.cpp.web.service.datafactory.ParsingLogService;
  11. import com.cpp.web.service.overhaulplan.OverhaulPlanService;
  12. import com.cpp.web.utils.*;
  13. import lombok.AllArgsConstructor;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.apache.commons.io.FileUtils;
  16. import org.apache.commons.lang3.time.DateFormatUtils;
  17. import org.springframework.scheduling.annotation.Scheduled;
  18. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  19. import org.springframework.stereotype.Service;
  20. import java.io.*;
  21. import java.math.BigDecimal;
  22. import java.math.RoundingMode;
  23. import java.nio.charset.StandardCharsets;
  24. import java.nio.file.Files;
  25. import java.text.ParseException;
  26. import java.text.SimpleDateFormat;
  27. import java.util.*;
  28. /**
  29. * ftp文件解析
  30. *
  31. * @author tl
  32. * @date 2022-05-11 09:51:21
  33. */
  34. @AllArgsConstructor
  35. @Slf4j
  36. @Service
  37. public class CloudFileParsing {
  38. private final ParsingLogService parsingLogService;
  39. private final ForecastPowerShortTermCloudService forecastPowerShortTermCloudService;
  40. private final NwpCloudService nwpCloudService;
  41. private final File fileNewDir = ParsingFileUtil.checkGetPath(ParsingFileUtil.getOutDownload() + File.separator + "new");
  42. private final ThreadPoolTaskExecutor executor;
  43. private final OverhaulPlanService overhaulPlanService;
  44. /**
  45. * 解析文件方法
  46. * 逻辑:先配置识别文件名称类型:识别文件名称关键字对应的文件类型
  47. * 有文件类型的配置才可以进入下一步
  48. * <p>
  49. * 查找各场站配置的ftp目录,去下载文件并识别文件类型执行对应的解析策略
  50. * <p>
  51. * 必要条件:1.配置文件识别类型。2.配置下载路径。3.配置解析公式
  52. *
  53. * @param
  54. * @return
  55. */
  56. public void parsingFile() {
  57. log.info("-----------------开始执行预测文件解析任务----------------------");
  58. Long currentDate = DateTimeUtil.getMillisecondsSubDay();//今日凌晨
  59. boolean flag = false;
  60. //判断该目录是否存在,不存在时创建
  61. if (!fileNewDir.exists()) {
  62. fileNewDir.mkdirs();
  63. log.info("【" + fileNewDir.getPath() + "】目录不存在,系统自动创建文件目录");
  64. }
  65. log.info("系统扫描路径【" + fileNewDir.getPath() + "】");
  66. // 获取指定目录下的文件
  67. Collection<File> files = FileUtils.listFiles(fileNewDir, new String[]{"RB", "txt"}, false);
  68. //当前时间格式化为年月日
  69. String dayStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
  70. // 如果指定目录下有文件
  71. if (files.size() > 0) {
  72. List<ParsingLog> parsingLogs = new ArrayList<>();
  73. // 循环文件并解析
  74. for (File file : files) {
  75. ParsingLog parsingLog = new ParsingLog();
  76. flag = false;
  77. String fileName = file.getName();
  78. parsingLog.setDataSources(DataSourcesEnum.E2);
  79. parsingLog.setParsingTime(new Date());
  80. parsingLog.setFileName(fileName);
  81. // 如果文件不是当然的,删除文件
  82. if (!fileName.contains(dayStr)) {
  83. file.delete();
  84. log.warn(fileName + "不是当天的文件,删除!");
  85. break;
  86. }
  87. // 如果文件名长度符合规则
  88. if (fileName.length() < 30) {
  89. // 如果是短期文件
  90. if (file.getName().startsWith("DQ")) {
  91. try {
  92. parsingLog.setFileType(FileTypeEnum.dq);
  93. // 解析短期文件
  94. List<ForecastPowerShortTermCloud> listDq = fileAnalysisShortTerm(file, new Date(currentDate));
  95. if (!listDq.isEmpty()) {
  96. try {
  97. parsingLog.setStationCode(listDq.get(0).getStationCode());
  98. forecastPowerShortTermCloudService.saveBatch(listDq);
  99. flag = true;
  100. } catch (Exception e) {
  101. log.error("保存短期数据报错:" + fileName, e);
  102. parsingLog.setParsingDescribe("保存短期数据报错:" + fileName);
  103. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4,"保存短期数据报错:" + fileName,null);
  104. flag = false;
  105. }
  106. } else {
  107. log.info(file.getName() + "文件数据内容为空、不能正常解析 、移除该文件:" + fileName);
  108. parsingLog.setParsingDescribe("文件数据内容为空、不能正常解析 、移除该文件:" + fileName);
  109. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4,"文件数据内容为空、不能正常解析 、移除该文件::" + fileName,null);
  110. flag = false;
  111. }
  112. } catch (Exception e) {
  113. flag = false;
  114. parsingLog.setParsingDescribe("解析DQ文件异常:" + fileName);
  115. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4,"解析DQ文件失败:" + fileName,null);
  116. log.error("解析DQ文件失败:" + fileName, e);
  117. }
  118. }
  119. if (file.getName().startsWith("NWP")) {
  120. try {
  121. parsingLog.setFileType(FileTypeEnum.nwp);
  122. List<NwpCloud> listNwp = fileAnalysisNwp(file, new Date(currentDate));
  123. if (!listNwp.isEmpty()) {
  124. try {
  125. parsingLog.setStationCode(listNwp.get(0).getStationCode());
  126. nwpCloudService.saveBatch(listNwp);
  127. flag = true;
  128. } catch (Exception e) {
  129. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4,"保存NWP数据报错:" + fileName,null);
  130. log.error("保存NWP数据报错:" + fileName, e);
  131. parsingLog.setParsingDescribe("保存NWP数据报错:" + fileName);
  132. flag = false;
  133. }
  134. } else {
  135. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4,"文件数据内容为空、不能正常解析 、移除该文件:" + fileName,null);
  136. parsingLog.setParsingDescribe("文件数据内容为空、不能正常解析 、移除该文件:" + fileName);
  137. log.info(file.getName() + "文件数据内容为空、不能正常解析 、移除该文件");
  138. flag = false;
  139. }
  140. } catch (Exception e) {
  141. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4,"解析NWP文件失败:" + fileName,null);
  142. log.error("解析NWP文件失败:" + fileName, e);
  143. parsingLog.setParsingDescribe("解析NWP文件失败:" + fileName);
  144. flag = false;
  145. }
  146. }
  147. if (flag) {
  148. parsingLog.setParsingFileStatus("成功");
  149. moveFile(file);
  150. } else {
  151. parsingLog.setParsingFileStatus("失败");
  152. LogUtil.info(DataSourcesEnum.E2, AlarmEnum.E4, parsingLog.getParsingDescribe(), "");
  153. //移除文件备份到error文件下
  154. moveFileError(file);
  155. }
  156. parsingLogs.add(parsingLog);
  157. }
  158. }
  159. if (parsingLogs.size() > 0) {
  160. parsingLogService.saveBatch(parsingLogs);
  161. }
  162. }
  163. log.info("-----------------执行预测文件解析任务完成----------------------");
  164. }
  165. /**
  166. * NWP解析
  167. *
  168. * @param file 文件路径
  169. * @return 样例集合
  170. */
  171. private List<NwpCloud> fileAnalysisNwp(File file, Date currentDate) {
  172. List<NwpCloud> listNwp = new ArrayList<>();
  173. if (file.renameTo(file)) {
  174. InputStreamReader readNwp = null;
  175. BufferedReader bufferedReaderNwp = null;
  176. try {
  177. readNwp = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);//考虑到编码格式
  178. bufferedReaderNwp = new BufferedReader(readNwp);
  179. String lineTxt;
  180. NwpCloud nwpData;
  181. BigDecimal nwpDirectRadiation = new BigDecimal("0.7"); //直接辐射
  182. BigDecimal nwpDiffuseRadiation = new BigDecimal("0.3"); //散接辐射
  183. String stationCode = "";
  184. String forecastModel = "";
  185. while ((lineTxt = bufferedReaderNwp.readLine()) != null) {
  186. //NWP文件按照Tab方式截取
  187. String[] datas = lineTxt.split("\t");
  188. if (datas[0].startsWith("<集中")) {
  189. stationCode = ParsingUtil.splitLineWithSpace(datas[0])[1].split("'")[1];
  190. // 使用单引号分割字符串
  191. forecastModel = ParsingUtil.splitLineWithSpace(datas[0])[2].split("'")[1];
  192. }
  193. if (!stationCode.equals("") && !forecastModel.equals("") && datas.length >= 35 && datas[0].startsWith("#")) {
  194. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  195. //过滤当天的数据
  196. //if (sdf.parse(datas[5]).getTime() >= TimeUtils.getMillisecondsSubDay() + 24 * 60 * 60 *
  197. // 1000) {
  198. Date time = sdf.parse(datas[5]);
  199. Integer howLongAgo = calcHowLongAgo(currentDate, time);
  200. if (howLongAgo > 0) {
  201. nwpData = new NwpCloud();
  202. //将截取的文件放入nwpData中
  203. nwpData.setForecastHowLongAgo(howLongAgo);
  204. nwpData.setForecastModel(forecastModel);
  205. nwpData.setStationCode(stationCode);
  206. nwpData.setTime(time);//采集时间 与 短期预测时间关联
  207. nwpData.setT(NumberUtil.subtract(new BigDecimal(datas[6]), new BigDecimal("273.15")));//温度
  208. nwpData.setSenf(new BigDecimal(datas[11]).setScale(2, RoundingMode.HALF_UP));//感热
  209. nwpData.setSwr(new BigDecimal(datas[9]).setScale(2, RoundingMode.HALF_UP));//短波辐射(相当于总辐射)
  210. nwpData.setLwr(new BigDecimal(datas[10]).setScale(2, RoundingMode.HALF_UP));//短波辐射(相当于总辐射)
  211. nwpData.setPressure(new BigDecimal(datas[8]).setScale(2, RoundingMode.HALF_UP));//地表气压
  212. nwpData.setRh(new BigDecimal(datas[7]).setScale(2, RoundingMode.HALF_UP));//2m相对湿度
  213. nwpData.setDiffuseRadiation(new BigDecimal(datas[9]).multiply(nwpDiffuseRadiation).setScale(2, RoundingMode.HALF_UP));//散接辐射
  214. nwpData.setDirectRadiation(new BigDecimal(datas[9]).multiply(nwpDirectRadiation).setScale(2, RoundingMode.HALF_UP));//直接辐射
  215. nwpData.setWs10(new BigDecimal(datas[19]).setScale(2, RoundingMode.HALF_UP));
  216. nwpData.setWs30(new BigDecimal(datas[20]).setScale(2, RoundingMode.HALF_UP));
  217. nwpData.setWs50(new BigDecimal(datas[21]).setScale(2, RoundingMode.HALF_UP));
  218. nwpData.setWs70(new BigDecimal(datas[22]).setScale(2, RoundingMode.HALF_UP));
  219. nwpData.setWs80(new BigDecimal(datas[23]).setScale(2, RoundingMode.HALF_UP));
  220. nwpData.setWs90(new BigDecimal(datas[24]).setScale(2, RoundingMode.HALF_UP));
  221. nwpData.setWs100(new BigDecimal(datas[25]).setScale(2, RoundingMode.HALF_UP));
  222. nwpData.setWs170(new BigDecimal(datas[26]).setScale(2, RoundingMode.HALF_UP));
  223. nwpData.setWd10(new BigDecimal(datas[27]).setScale(2, RoundingMode.HALF_UP));
  224. nwpData.setWd30(new BigDecimal(datas[28]).setScale(2, RoundingMode.HALF_UP));
  225. nwpData.setWd50(new BigDecimal(datas[29]).setScale(2, RoundingMode.HALF_UP));
  226. nwpData.setWd70(new BigDecimal(datas[30]).setScale(2, RoundingMode.HALF_UP));
  227. nwpData.setWd80(new BigDecimal(datas[31]).setScale(2, RoundingMode.HALF_UP));
  228. nwpData.setWd90(new BigDecimal(datas[32]).setScale(2, RoundingMode.HALF_UP));
  229. nwpData.setWd100(new BigDecimal(datas[33]).setScale(2, RoundingMode.HALF_UP));
  230. nwpData.setWd170(new BigDecimal(datas[34]).setScale(2, RoundingMode.HALF_UP));
  231. if (datas.length > 35) {
  232. //nwp 新增解析内容
  233. nwpData.setWs20(new BigDecimal(datas[35]).setScale(2, RoundingMode.HALF_UP));
  234. nwpData.setWs40(new BigDecimal(datas[36]).setScale(2, RoundingMode.HALF_UP));
  235. nwpData.setWs60(new BigDecimal(datas[37]).setScale(2, RoundingMode.HALF_UP));
  236. nwpData.setWs110(new BigDecimal(datas[38]).setScale(2, RoundingMode.HALF_UP));
  237. nwpData.setWs120(new BigDecimal(datas[39]).setScale(2, RoundingMode.HALF_UP));
  238. nwpData.setWs130(new BigDecimal(datas[40]).setScale(2, RoundingMode.HALF_UP));
  239. nwpData.setWs140(new BigDecimal(datas[41]).setScale(2, RoundingMode.HALF_UP));
  240. nwpData.setWs150(new BigDecimal(datas[42]).setScale(2, RoundingMode.HALF_UP));
  241. nwpData.setWs160(new BigDecimal(datas[43]).setScale(2, RoundingMode.HALF_UP));
  242. nwpData.setWs180(new BigDecimal(datas[44]).setScale(2, RoundingMode.HALF_UP));
  243. nwpData.setWs190(new BigDecimal(datas[45]).setScale(2, RoundingMode.HALF_UP));
  244. nwpData.setWs200(new BigDecimal(datas[46]).setScale(2, RoundingMode.HALF_UP));
  245. nwpData.setWd20(new BigDecimal(datas[47]).setScale(2, RoundingMode.HALF_UP));
  246. nwpData.setWd40(new BigDecimal(datas[48]).setScale(2, RoundingMode.HALF_UP));
  247. nwpData.setWd60(new BigDecimal(datas[49]).setScale(2, RoundingMode.HALF_UP));
  248. nwpData.setWd110(new BigDecimal(datas[50]).setScale(2, RoundingMode.HALF_UP));
  249. nwpData.setWd120(new BigDecimal(datas[51]).setScale(2, RoundingMode.HALF_UP));
  250. nwpData.setWd130(new BigDecimal(datas[52]).setScale(2, RoundingMode.HALF_UP));
  251. nwpData.setWd140(new BigDecimal(datas[53]).setScale(2, RoundingMode.HALF_UP));
  252. nwpData.setWd150(new BigDecimal(datas[54]).setScale(2, RoundingMode.HALF_UP));
  253. nwpData.setWd160(new BigDecimal(datas[55]).setScale(2, RoundingMode.HALF_UP));
  254. nwpData.setWd180(new BigDecimal(datas[56]).setScale(2, RoundingMode.HALF_UP));
  255. nwpData.setWd190(new BigDecimal(datas[57]).setScale(2, RoundingMode.HALF_UP));
  256. nwpData.setWd200(new BigDecimal(datas[58]).setScale(2, RoundingMode.HALF_UP));
  257. //下面的感觉用不上,先注释
  258. // nwpData.setT10(new BigDecimal(datas[59]).setScale(2, RoundingMode.HALF_UP));
  259. // nwpData.setT20(new BigDecimal(datas[60]).setScale(2, RoundingMode.HALF_UP));
  260. // nwpData.setT30(new BigDecimal(datas[61]).setScale(2, RoundingMode.HALF_UP));
  261. // nwpData.setT40(new BigDecimal(datas[62]).setScale(2, RoundingMode.HALF_UP));
  262. // nwpData.setT50(new BigDecimal(datas[63]).setScale(2, RoundingMode.HALF_UP));
  263. // nwpData.setT60(new BigDecimal(datas[64]).setScale(2, RoundingMode.HALF_UP));
  264. // nwpData.setT70(new BigDecimal(datas[65]).setScale(2, RoundingMode.HALF_UP));
  265. // nwpData.setT80(new BigDecimal(datas[66]).setScale(2, RoundingMode.HALF_UP));
  266. // nwpData.setT90(new BigDecimal(datas[67]).setScale(2, RoundingMode.HALF_UP));
  267. // nwpData.setT100(new BigDecimal(datas[68]).setScale(2, RoundingMode.HALF_UP));
  268. // nwpData.setT110(new BigDecimal(datas[69]).setScale(2, RoundingMode.HALF_UP));
  269. // nwpData.setT120(new BigDecimal(datas[70]).setScale(2, RoundingMode.HALF_UP));
  270. // nwpData.setT130(new BigDecimal(datas[71]).setScale(2, RoundingMode.HALF_UP));
  271. // nwpData.setT140(new BigDecimal(datas[72]).setScale(2, RoundingMode.HALF_UP));
  272. // nwpData.setT150(new BigDecimal(datas[73]).setScale(2, RoundingMode.HALF_UP));
  273. // nwpData.setT160(new BigDecimal(datas[74]).setScale(2, RoundingMode.HALF_UP));
  274. // nwpData.setT170(new BigDecimal(datas[75]).setScale(2, RoundingMode.HALF_UP));
  275. // nwpData.setT180(new BigDecimal(datas[76]).setScale(2, RoundingMode.HALF_UP));
  276. // nwpData.setT190(new BigDecimal(datas[77]).setScale(2, RoundingMode.HALF_UP));
  277. // nwpData.setT200(new BigDecimal(datas[78]).setScale(2, RoundingMode.HALF_UP));
  278. // nwpData.setDniCalcd(new BigDecimal(datas[79]).setScale(2, RoundingMode.HALF_UP));
  279. // nwpData.setSolarZenith(new BigDecimal(datas[80]).setScale(2, RoundingMode.HALF_UP));
  280. // nwpData.setClearskyGhi(new BigDecimal(datas[81]).setScale(2, RoundingMode.HALF_UP));
  281. // nwpData.setLcc(new BigDecimal(datas[82]).setScale(2, RoundingMode.HALF_UP));
  282. // nwpData.setMcc(new BigDecimal(datas[83]).setScale(2, RoundingMode.HALF_UP));
  283. // nwpData.setHcc(new BigDecimal(datas[84]).setScale(2, RoundingMode.HALF_UP));
  284. // nwpData.setTcc(new BigDecimal(datas[85]).setScale(2, RoundingMode.HALF_UP));
  285. nwpData.setTpr(new BigDecimal(datas[86]).setScale(2, RoundingMode.HALF_UP));
  286. }
  287. listNwp.add(nwpData);
  288. }
  289. }
  290. }
  291. } catch (IOException | ParseException | RuntimeException e) {
  292. log.error("系统错误:", e);
  293. File destFile = new File(file.getPath().replaceFirst("new", "error"));
  294. if (destFile.exists()) {
  295. destFile.delete();
  296. }
  297. try {
  298. FileUtils.moveFile(file, destFile);
  299. } catch (IOException e1) {
  300. log.error(file.getName() + "文件解析失败", e);
  301. }
  302. } finally {
  303. close(bufferedReaderNwp, readNwp);
  304. }
  305. }
  306. return listNwp;
  307. }
  308. /**
  309. * 短期解析
  310. *
  311. * @param file 文件路径
  312. * @param currentDate 当前时间
  313. * @return 样例集合
  314. */
  315. private List<ForecastPowerShortTermCloud> fileAnalysisShortTerm(File file, Date currentDate) {
  316. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  317. List<ForecastPowerShortTermCloud> forecastPowerShortTerm = new ArrayList<>();
  318. // 当文件未被使用时,进行解析上报
  319. if (file.renameTo(file)) {
  320. InputStreamReader read = null;
  321. BufferedReader bufferedReader = null;
  322. String stringLine;
  323. ForecastPowerShortTermCloud stf;
  324. try {
  325. read = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);
  326. bufferedReader = new BufferedReader(read);
  327. String stationCode = "";
  328. String forecastModel = "";
  329. // 循环解析文件
  330. while ((stringLine = bufferedReader.readLine()) != null) {
  331. String[] string_arr = stringLine.split("\t");
  332. if (string_arr[0].startsWith("<集中")) {
  333. stationCode = ParsingUtil.splitLineWithSpace(string_arr[0])[1].split("'")[1];
  334. // 使用单引号分割字符串
  335. forecastModel = ParsingUtil.splitLineWithSpace(string_arr[0])[2].split("'")[1];
  336. }
  337. if (string_arr.length == 4) {
  338. if (!stationCode.equals("") && !forecastModel.equals("") && string_arr[0].startsWith("#")) {
  339. if (StringUtils.isNotEmpty(string_arr[2])) {
  340. Date time = sdf.parse(string_arr[2]);
  341. Integer howLongAgo = calcHowLongAgo(currentDate, time);
  342. if (howLongAgo > 0) {
  343. stf = new ForecastPowerShortTermCloud();
  344. stf.setFpValue(new BigDecimal(string_arr[3]));
  345. stf.setTime(time);
  346. stf.setForecastHowLongAgo(howLongAgo);
  347. stf.setStationCode(stationCode);
  348. stf.setForecastModel(forecastModel);
  349. forecastPowerShortTerm.add(stf);
  350. }
  351. }
  352. }
  353. }
  354. }
  355. } catch (IOException | ParseException | RuntimeException e) {
  356. log.error("系统错误:", e);
  357. File destFile = new File(file.getPath().replaceFirst("new", "error"));
  358. if (destFile.exists()) {
  359. destFile.delete();
  360. }
  361. try {
  362. FileUtils.moveFile(file, destFile);
  363. } catch (IOException e1) {
  364. log.error(file.getName() + "文件解析失败", e);
  365. }
  366. } finally {
  367. close(bufferedReader, read);
  368. }
  369. }
  370. return overhaulPlanService.getCorrectionData(forecastPowerShortTerm,"","");
  371. }
  372. /**
  373. * 关闭文件流
  374. *
  375. * @param bufferedReader 字符数据
  376. * @param read 字节流
  377. */
  378. private void close(BufferedReader bufferedReader, InputStreamReader read) {
  379. try {
  380. if (bufferedReader != null) {
  381. bufferedReader.close();
  382. }
  383. if (read != null) {
  384. read.close();
  385. }
  386. } catch (IOException e) {
  387. log.error("关闭文件流失败:", e);
  388. }
  389. }
  390. /**
  391. * 计算D+x中的x
  392. *
  393. * @param baseTime
  394. * @param time
  395. */
  396. public Integer calcHowLongAgo(Date baseTime, Date time) {
  397. return ((int) ((time.getTime() - baseTime.getTime()) / 86400000L));
  398. }
  399. /**
  400. * 移动文件到临时目录下
  401. *
  402. * @param file 文件
  403. */
  404. private void moveFile(File file) {
  405. // 移动文件到处理目录
  406. File destFile = new File(file.getPath().replaceFirst("new", "backupsTemp"));
  407. log.info("move file :{}, dest file:{}", file, destFile);
  408. if (destFile.exists()) {
  409. destFile.delete();
  410. }
  411. try {
  412. FileUtils.moveFile(file, destFile);
  413. } catch (IOException e) {
  414. log.error("系统移除文件错误:", e);
  415. }
  416. moveFileBackups(destFile.getParent());
  417. }
  418. /**
  419. * 移动文件到处理目录
  420. *
  421. * @param filePath 文件路径
  422. */
  423. private void moveFileBackups(String filePath) {
  424. String targetRoot = filePath.replaceFirst("backupsTemp", "backups");
  425. String path = mkDirForTime(targetRoot, null);
  426. path = mkDirForTime(path, "yyyy");
  427. path = mkDirForTime(path, "MM");
  428. path = mkDirForTime(path, "yyyyMMdd");
  429. path = mkDirForTime(path, "HHmm");
  430. // 移动文件夹内容
  431. File sourceFile = new File(filePath);
  432. if (sourceFile.exists()) {
  433. try {
  434. File[] files = sourceFile.listFiles();
  435. if (files != null) {
  436. for (File f : files) {
  437. if (f.renameTo(new File(path + f.getName()))) {
  438. log.info("move file :{}, dest file:{}", path, f.getName());
  439. }
  440. }
  441. }
  442. } catch (Exception e) {
  443. log.error("文件移动失败" + e);
  444. }
  445. }
  446. }
  447. /**
  448. * 创建备份文件夹
  449. */
  450. public static String mkDirForTime(String targetRoot, String format) {
  451. String path;
  452. File file;
  453. if (StringUtils.isNotEmpty(format)) {
  454. long current = System.currentTimeMillis();
  455. path = DateFormatUtils.format(current, format);
  456. file = new File(targetRoot + File.separator + path + File.separator);
  457. } else {
  458. file = new File(targetRoot + File.separator);
  459. }
  460. if (!file.exists() && !file.isFile()) {
  461. if (file.mkdir()) {
  462. log.info("已创建文件夹");
  463. } else {
  464. log.info("创建文件夹失败,路径:" + file.getPath());
  465. }
  466. }
  467. return file.getPath() + File.separator;
  468. }
  469. /**
  470. * 移动文件到处理错误目录下
  471. *
  472. * @param file 文件
  473. */
  474. private void moveFileError(File file) {
  475. File destFile = new File(file.getPath().replaceFirst("new", "error"));
  476. if (destFile.exists()) {
  477. destFile.delete();
  478. }
  479. try {
  480. FileUtils.moveFile(file, destFile);
  481. } catch (IOException e) {
  482. log.error(file.getName() + "文件解析失败", e);
  483. }
  484. }
  485. }