package com.se.nsl.service; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMapper; import com.se.nsl.config.PropertiesConfig; import com.se.nsl.domain.dto.*; import com.se.nsl.domain.po.Rainfall; import com.se.nsl.domain.po.Simu; import com.se.nsl.domain.po.SimuData; import com.se.nsl.domain.vo.ConfigVo; import com.se.nsl.helper.ComHelper; import com.se.nsl.helper.GdalHelper; import com.se.nsl.helper.StringHelper; import com.se.nsl.helper.WebHelper; import com.se.nsl.utils.AreaType; import com.se.nsl.utils.RainFallUnit; import com.se.nsl.utils.SimulateType; import com.se.nsl.utils.TimeFormatUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.gdal.gdal.Band; import org.gdal.gdal.Dataset; import org.gdal.gdal.gdal; import org.gdal.gdalconst.gdalconstConstants; import org.gdal.ogr.Geometry; import org.gdal.ogr.ogr; import org.gdal.osr.CoordinateTransformation; import org.gdal.osr.SpatialReference; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; @Slf4j @Service @SuppressWarnings("ALL") public class ResolveService { @Resource SimuService simuService; @Resource PropertiesConfig config; @Resource UwService uwService; @Resource TestService testService; private ObjectMapper mapper = new ObjectMapper(); Integer DIGIT = 1000000; SimpleDateFormat YYYYMDHM = new SimpleDateFormat("yyyy M d H m "); List MODES = new ArrayList<>(Arrays.asList("正态分布", "平均分布", "波动平均分布", "持续上升")); public int start(Simu simu) { Date now = new Date(); String date = StringHelper.YMDHMS2_FORMAT.format(now); // 将WKT转换为Geometry对象 Geometry geom = Geometry.CreateFromWkt(simu.getGeom()); if (geom.GetGeometryType() == ogr.wkbMultiPolygon) { geom = geom.GetGeometryRef(0); } double[] envelope = new double[4]; geom.GetEnvelope(envelope); SimuData data = JSON.parseObject(simu.getData(), SimuData.class); data.setInPath(date); data.setOutPath(date); data.setEnvelope(envelope); data.setEpsg(config.getEpsg()); simu.setData(JSON.toJSONString(data)); simu.setServiceName(date); simu.setStatus(1); // 0-创建仿真,1-预处理,2-分析中,10-完成,20-出错 simu.setUpdateTime(new Timestamp(now.getTime())); int rows = simuService.updateById(simu); if (rows > 0) { asyncCall(simu); } return rows; } private void asyncCall(Simu simu) { ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable() { @Override @SneakyThrows public void run() { cope(simu); } }); executor.shutdown(); } private void cope(Simu simu) { try { SimuData data = JSONUtil.toBean(simu.getData(), SimuData.class); update(simu, 1, "初始化参数"); initArgs(simu, data); createRainfallFile(simu, data); update(simu, 2, "调用求解器"); callUwSolver(simu, data); update(simu, 3, "调用Zarr转Tif"); callZarr2tif(data); update(simu, 4, "解析数据"); createNsl(data); update(simu, 10, "完成"); log.info("模拟完成"); } catch (Exception ex) { log.error(ex.getMessage(), ex); update(simu, 20, ex.getMessage()); } } private void update(Simu simu, int status, String rs) { simu.setStatus(status); if (null != rs) simu.setResult(rs); simu.setUpdateTime(WebHelper.getCurrentTimestamp()); simuService.updateById(simu); } /** * 初始化参数 */ public void initArgs(Simu simu, SimuData data) { String inPath = config.getInPath() + File.separator + data.getInPath(); createDir(inPath); createDir(inPath + File.separator + "depth"); createDir(inPath + File.separator + "velocity"); createDir(config.getOutPath() + File.separator + data.getOutPath()); Short areaType = simu.getAreaType(); AreaType at = AreaType.of(areaType); String terrainTif = config.getSourceDem(); String landuseTif = config.getSourceLanduse(); String stationTif = null; if (at == AreaType.KEY_DITCH) { File keyDitchDir = new File(config.getKeyDitch()); String areaName = simu.getAreaName(); Optional first = Arrays.stream(keyDitchDir.listFiles()).filter(f -> f.getName().equals(areaName)).findFirst(); if (first.isPresent()) { File targetTifDir = first.get(); File[] files = targetTifDir.listFiles(); for (File file : files) { String name = file.getName(); if (name.toLowerCase().contains("dem")) { terrainTif = file.getAbsolutePath(); } if (name.toLowerCase().contains("landuse")) { landuseTif = file.getAbsolutePath(); } if (name.toLowerCase().contains("station")) { stationTif = file.getAbsolutePath(); } } } } Geometry geom = Geometry.CreateFromWkt(simu.getGeom()); if (geom.GetGeometryType() == ogr.wkbMultiPolygon) geom = geom.GetGeometryRef(0); SpatialReference dstSR = GdalHelper.createSpatialReference(config.getEpsg()); CoordinateTransformation ct = CoordinateTransformation.CreateCoordinateTransformation(GdalHelper.SR4326, dstSR); geom.Transform(ct); String wkt = geom.ExportToWkt(); String terrainFile = inPath + File.separator + config.getTerrainFile(); Dataset dsDem = gdal.Open(terrainTif, gdalconstConstants.GA_ReadOnly); ComHelper.cutAndResample(dsDem, null, terrainFile, null, wkt, null, null); dsDem.delete(); String landuseFile = inPath + File.separator + config.getLanduseFile(); Dataset dsLanduse = gdal.Open(landuseTif, gdalconstConstants.GA_ReadOnly); ComHelper.cutAndResample(dsLanduse, null, landuseFile, null, wkt, null, null); dsLanduse.delete(); if (stationTif != null) { String stationFile = inPath + File.separator + "Station.tif"; Dataset dsStation = gdal.Open(stationTif, gdalconstConstants.GA_ReadOnly); ComHelper.cutAndResample(dsStation, null, stationFile, null, wkt, null, null); dsStation.delete(); } } public void updateTif(Simu simu, SimuData data2) { Dataset ds = gdal.Open(config.getSourceLanduse(), gdalconstConstants.GA_Update); // 以读写模式打开TIFF文件 Band band = ds.GetRasterBand(1); if (band.GetRasterDataType() != gdalconstConstants.GDT_Byte) { System.err.println("错误:非Byte类型数据"); ds.delete(); return; } int width = band.getXSize(); int height = band.getYSize(); // 读取Byte类型数据 byte[] data = new byte[width * height]; band.ReadRaster(0, 0, width, height, data); // 替换0值为8(注意Java的byte是有符号的,需处理0-255范围) for (int i = 0; i < data.length; i++) { if ((data[i] & 0xFF) == 0) { // 无符号比较 data[i] = (byte) 8; } } band.WriteRaster(0, 0, width, height, data); // 写回数据并保存 band.SetNoDataValue(8.0); // 设置新Nodata值 band.FlushCache(); // 强制写入更改 ds.delete(); } private void createDir(String path) { File f = new File(path); if (f.exists() && f.isDirectory()) { FileUtil.del(f); } f.mkdirs(); } public void createRainfallFile(Simu simu, SimuData data) throws Exception { List rainfalls = data.getRainfalls(); if (null == rainfalls || rainfalls.size() < 2) createRainfall(simu); String dat = config.getInPath() + File.separator + "Rainfalls" + File.separator + simu.getId() + ".dat"; String rainfallFile = config.getInPath() + File.separator + data.getInPath() + File.separator + "rainfall.dat"; if (new File(dat).exists()) { Files.copy(Paths.get(dat), Paths.get(rainfallFile), StandardCopyOption.REPLACE_EXISTING); return; } List list = new ArrayList<>(); list.add(config.getRainfallTitle()); double centerX = ComHelper.getMinVal((data.getMinx() + data.getMaxx()) / 2, DIGIT); double centerY = ComHelper.getMinVal((data.getMiny() + data.getMaxy()) / 2, DIGIT); String prefix = config.getRainfallSite() + " " + centerX + " " + centerY + " "; //如果没有单位或者单位为mm/h则按照 mm/h计算,否则按照mm/5min计算 // int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5; String iu = data.getIntensityUnit(); RainFallUnit rfUnit = RainFallUnit.of(iu); data.setIntensityUnit(rfUnit.getUnit()); int unit = rfUnit.getC(); int c = rainfalls.size() - 1; for (int i = 0; i < c; i++) { Rainfall r1 = rainfalls.get(i); Rainfall r2 = rainfalls.get(i + 1); list.addAll(calcRainfall(r1, r2, prefix, unit)); } //list.add(prefix + YYYYMDHM.format(rainfalls.get(c).getTime()) + getMinVal(rainfalls.get(c).getIntensity() / unit, DIGIT)); list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(rainfalls.get(c).getTime()), getMinVal(rainfalls.get(c).getIntensity() / unit, DIGIT))); // list.add(0, "1 " + (list.size() - 1)); Files.write(Paths.get(rainfallFile), list, StandardCharsets.UTF_8); } public static double getMinVal(double val, double radix) { return ((long) Math.floor(val * radix)) / radix; } // beijing 116.0 40.0 2025 1 1 0 13 1.666666 private List calcRainfall(Rainfall r1, Rainfall r2, String prefix, int unit) { long mins = Math.abs(r2.getTime().getTime() - r1.getTime().getTime()) / (1000 * 60); // 计算分钟数 double diff = (r2.getIntensity() - r1.getIntensity()) / mins / unit; //ComHelper.getMinVal((r1.getIntensity() - r2.getIntensity()) / mins / unit, DIGIT); Calendar cal = Calendar.getInstance(); cal.setTime(r1.getTime()); List list = new ArrayList<>(); double intensity = ComHelper.getMinVal(r1.getIntensity() / unit, DIGIT); for (int i = 0; i < mins; i++) { //list.add(prefix + YYYYMDHM.format(cal.getTime()) + getMinVal((intensity + diff * i), DIGIT)); list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(cal.getTime()), getMinVal((intensity + diff * i), DIGIT))); cal.add(Calendar.MINUTE, 1); } return list; } /** * 调用UWSolver */ public String callUwSolver(Simu simu, SimuData data) throws Exception { int duration = 3600 * data.getDuration(); // 秒数 if (null != data.getRainfalls() && data.getRainfalls().size() > 1) { List rainfalls = data.getRainfalls(); int size = rainfalls.size(); Rainfall last = rainfalls.get(size - 1); Rainfall first = rainfalls.get(0); Instant end = last.getTime().toInstant(); Instant start = first.getTime().toInstant(); long diff = ChronoUnit.SECONDS.between(end, start); duration = (int) (Math.abs(diff)); } String inPath = config.getInPath() + File.separator + data.getInPath(); String terrainFile = inPath + File.separator + config.getTerrainFile(); String landuseFile = inPath + File.separator + config.getLanduseFile(); String rainfallFile = (inPath + File.separator + "rainfall.dat"); String saveName = inPath + File.separator + "result.zarr"; // ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames()); Integer saveFrameInterval = config.getSaveFrameInterval(); int saveFrames = duration / 60 / saveFrameInterval; Short type = simu.getType(); SimulateType simulateType = SimulateType.of(type); String saveMode = simulateType.getSaveMode(); String startTime = TimeFormatUtil.formatDate(data.getStartTime()); ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, saveFrames, saveMode, startTime); vo.getResult().setSave_filter(config.getSaveFilter()); String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json"; // ComHelper.writeJson(configFile, JSON.toJSONString(vo)); mapper.writeValue(new File(configFile), vo); String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), configFile); return callBat2(cmd); } /** * 调用zarr2tif */ public String callZarr2tif(SimuData data) throws Exception { String inPath = config.getInPath() + File.separator + data.getInPath(); String zarrFile = inPath + File.separator + "result.zarr"; String geotiffDir = inPath + File.separator + "depth"; String terrainFile = inPath + File.separator + config.getTerrainFile(); String jsonPath = inPath + File.separator + "zarr2tif.json"; Zarr2Tif zarr2Tif = new Zarr2Tif(zarrFile, geotiffDir, terrainFile, Collections.emptyList()); // ComHelper.writeJson(jsonPath, JSON.toJSONString(zarr2Tif)); mapper.writeValue(new File(jsonPath), zarr2Tif); String cmd = String.format("%s \"%s\"", config.getZarr2tifBat(), jsonPath); return callBat2(cmd); } private String callBat2(String cmd) { try { ProcessBuilder pb = new ProcessBuilder("cmd", "/c", cmd); pb.redirectErrorStream(true); // 合并错误流到标准输出 Process process = pb.start(); process.getOutputStream().close(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) { String line; while ((line = reader.readLine()) != null) { log.info(line); } } int exitCode = process.waitFor(); return "ok"; // sb.toString(); } catch (Exception ex) { log.error(ex.getMessage(), ex); return null; } } private String callBat(String cmd) { try { ProcessBuilder pb = new ProcessBuilder("cmd", "/c", cmd); pb.redirectErrorStream(true); // 合并错误流到标准输出 Process process = pb.start(); process.getOutputStream().close(); /*StringBuilder sb = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); sb.append(line); } }*/ int exitCode = process.waitFor(); return "ok"; // sb.toString(); } catch (Exception ex) { log.error(ex.getMessage(), ex); return null; } } private void createNsl(SimuData data) throws Exception { testService.test(data); } private void procTifs(String tifPath, String outPath, Date startTime) { SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); Calendar calendar = Calendar.getInstance(); calendar.setTime(startTime); for (File file : new File(tifPath).listFiles()) { if (!file.exists() || !file.isDirectory()) continue; File tif = new File(tifPath + "\\" + file.getName() + File.separator + "depth.tif"); if (!tif.exists() || tif.isDirectory()) continue; calendar.add(Calendar.SECOND, 1); String newName = df.format(calendar.getTime()); String newFile = outPath + File.separator + newName + ".tif"; System.out.println(newFile); tif.renameTo(new File(newFile)); file.delete(); } } public String createRainfallCsv(String csvPath, String mode, double total, double intensity, int hours) { // python 脚本名.py <参数1-csv文件名> <参数2-降雨模式:正态分布|平均分布|波动平均分布|持续上升> <参数3-降雨总量> <参数4-最大雨强> <参数5-降雨时间(分钟)> String cmd = String.format("%s \"%s\" \"%s\" %f %f %d", config.getCreateRainfall(), csvPath, mode, total, intensity, hours * 60); return callBat(cmd); } public void createRainfall(Simu simu) throws Exception { SimuData data = JSON.parseObject(simu.getData(), SimuData.class); if (null == data.getMode() || MODES.contains(data.getMode())) data.setMode(MODES.get(0)); if (StringUtils.isEmpty(data.getIntensityUnit())) data.setIntensityUnit("mm/h"); Geometry geom = Geometry.CreateFromWkt(simu.getGeom()); if (geom.GetGeometryType() == ogr.wkbMultiPolygon) geom = geom.GetGeometryRef(0); double[] envelope = new double[4]; geom.GetEnvelope(envelope); data.setEnvelope(envelope); data.setEpsg(config.getEpsg()); String basePath = config.getInPath() + File.separator + "Rainfalls"; if (!new File(basePath).exists()) new File(basePath).mkdirs(); if (null == simu.getCreateTime()) simu.setCreateTime(new Timestamp(new Date().getTime())); String csvPath = basePath + File.separator + simu.getId() + ".csv"; int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5; createRainfallCsv(csvPath, data.getMode(), data.getTotal(), data.getIntensity() / unit, data.getDuration()); List list = getValues(csvPath); if (!CollUtil.isEmpty(list)) { data.setRainfalls(new ArrayList<>()); setRainfalls(simu, data, list); } simu.setData(JSON.toJSONString(data)); } private List getValues(String csvPath) throws Exception { if (!new File(csvPath).exists()) return Collections.emptyList(); List list = Files.readAllLines(Paths.get(csvPath)); list.remove(0); return list.stream() .map(s -> new BigDecimal(s).setScale(6, RoundingMode.HALF_DOWN).doubleValue()) .collect(Collectors.toList()); } private void setRainfalls(Simu simu, SimuData data, List vals) throws Exception { String basePath = config.getInPath() + File.separator + "Rainfalls"; String dat = basePath + File.separator + simu.getId() + ".dat"; Calendar cal = Calendar.getInstance(); cal.setTime(data.getStartTime()); List list = new ArrayList<>(); list.add(config.getRainfallTitle()); double centerX = ComHelper.getMinVal((data.getMinx() + data.getMaxx()) / 2, DIGIT); double centerY = ComHelper.getMinVal((data.getMiny() + data.getMaxy()) / 2, DIGIT); String prefix = config.getRainfallSite() + " " + centerX + " " + centerY + " "; Double total = 0.0; for (int i = 0, c = vals.size(); i < c; i++) { total += vals.get(i); if (i % 15 == 0) { data.getRainfalls().add(new Rainfall(cal.getTime(), vals.get(i), total)); } list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(cal.getTime()), vals.get(i))); cal.add(Calendar.MINUTE, 1); } // list.add(0, "1 " + (list.size() - 1)); Files.write(Paths.get(dat), list, StandardCharsets.UTF_8); } //实时模拟 // public String realTimeSimulate(RealTimeInput input) throws IOException { // long currentTime = System.currentTimeMillis(); // //根据服务找到指定的文件夹 // String serviceName = input.getServiceName(); // File serviceNameDir = new File(config.getInPath(), serviceName); // //生成一个新的雨量文件,需要原先雨量文件的一些信息,所以需要先读取旧的 // String[] values = readTheOldFirstLineRainfallValue(serviceNameDir); // File newDatFile = generateNewRainfallFile(input, values, serviceNameDir, currentTime); // // //生成一个新的生成zarr的配置文件 // File newConfigFile = generateNewZarrConfigFile(serviceNameDir, serviceName, currentTime, newDatFile); // //执行求解器运算 // String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), newConfigFile); // callBat2(cmd); // // //生成一个新的zarr转tif的json文件 // File newZarr2TifJson = generateNewZarr2TifJson(serviceNameDir, currentTime); // //执行zarr转tif // String zarr2TifCmd = String.format("%s \"%s\"", config.getZarr2tifBat(), newZarr2TifJson); // callBat2(zarr2TifCmd); // //返回新的layer.json名称 // return generateLayerJsonAndPng(serviceName, serviceNameDir, currentTime); // // } // private String generateLayerJsonAndPng(String serviceName, File serviceNameDir, long currentTime) throws IOException { // ResultDto resultDto = new ResultDto(); // resultDto.setServiceName(serviceName); // File temp = Paths.get(config.getOutPath(), serviceName, "temp").toFile(); // if (!temp.exists()) temp.mkdir(); // resultDto.setTemp(temp.getAbsolutePath()); // resultDto.setOutPath(Paths.get(config.getOutPath(), serviceName).toString()); // File dem = new File(serviceNameDir, "DEM.tif"); // resultDto.setTerrainFile(dem.getAbsolutePath()); // File newDepthDir = new File(serviceNameDir + File.separator + "depth_" + currentTime); // resultDto.setWaterPath(newDepthDir.getAbsolutePath()); // LayerDto layerDto = new LayerDto(config.getVer(), 4548, config.getSizes()); // String newLayerJsonName = "layer_" + currentTime + ".json"; // layerDto.setName(newLayerJsonName); // testService.processRealTime(resultDto, layerDto); // return newLayerJsonName; // } // private File generateNewZarr2TifJson(File serviceNameDir, long currentTime) throws IOException { // File srcZarr2TifJson = new File(serviceNameDir, "zarr2tif.json"); // Zarr2Tif zarr2Tif = mapper.readValue(srcZarr2TifJson, Zarr2Tif.class); // //修改zarr2tif对象中的字段 //// String stamp = TimeFormatUtil.formatTime(currentTime, "yyyy-MM-dd HH:mm:ss"); //// zarr2Tif.setStart_timestamp(stamp); //// String newZarrPath = serviceNameDir + File.separator + "result_" + currentTime + ".zarr"; // String newZarrPath = serviceNameDir + File.separator + "result.zarr"; // zarr2Tif.setZarr_file(newZarrPath); // zarr2Tif.setGeotiff_dir(serviceNameDir + File.separator + "depth_" + currentTime); // File newZarr2TifJson = new File(serviceNameDir, "zarr2tif_" + currentTime + ".json"); // mapper.writeValue(newZarr2TifJson, zarr2Tif); // return newZarr2TifJson; // } // private File generateNewZarrConfigFile(File serviceNameDir, String serviceName, long currentTime, File newDatFile) throws IOException { // File configFile = new File(serviceNameDir, serviceName + ".json"); // ConfigVo configVo = mapper.readValue(configFile, ConfigVo.class); // int simulateTime = 300; //模拟时间,默认为5min,即300s // int intervalTime = 60; //每帧的间隔时间,默认为60s,60s生成一帧 // configVo.getRaingage().set(0, newDatFile.getAbsolutePath()); //raingage file // ResultVo result = configVo.getResult(); // Integer oldDuration = configVo.getDuration(); //// result.setSave_start(oldDuration); //起始时间要在上次时间的基础上开始 // configVo.setDuration(oldDuration + simulateTime); //固定为5min // result.setSave_interval(intervalTime); // result.setSave_frames(result.getSave_frames() + (simulateTime / intervalTime)); //保留5帧,在原来的基础上增加5帧 //// String newZarrPath = serviceNameDir + File.separator + "result_" + currentTime + ".zarr"; // String newZarrPath = serviceNameDir + File.separator + "result.zarr"; // result.setSave_name(newZarrPath); // File newConfigFile = new File(serviceNameDir, currentTime + ".json"); // mapper.writeValue(newConfigFile, configVo); // return newConfigFile; // } // private File generateNewRainfallFile(RealTimeInput input, String[] values, File serviceNameDir, long currentTime) throws IOException { // String station = values[0]; // double lon = Double.parseDouble(values[1]); // double lat = Double.parseDouble(values[2]); // String title = config.getRainfallTitle(); // List newLines = new ArrayList<>(); // newLines.add(title); // List data = input.getData(); // for (RealTimeInput.RealTimeData rd : data) { // LocalDateTime dateTime = rd.getDateTime(); // int year = dateTime.getYear(); // int month = dateTime.getMonthValue(); // int day = dateTime.getDayOfMonth(); // int hour = dateTime.getHour(); // int minute = dateTime.getMinute(); // double intensity = rd.getIntensity(); //保留指定位数小数 // String l = String.format("%s %s %s %s %s %s %s %s %s", // station, lon, lat, year, month, day, hour, minute, String.format("%.6f", intensity)); // newLines.add(l); // } // File newDatFile = new File(serviceNameDir, "rainfall_" + currentTime + ".dat"); // if (!newDatFile.exists()) newDatFile.createNewFile(); // Files.write(newDatFile.toPath(), newLines, StandardOpenOption.TRUNCATE_EXISTING); // return newDatFile; // } // private static String[] readTheOldFirstLineRainfallValue(File serviceNameDir) throws IOException { // File srcRailfallFile = new File(serviceNameDir, "rainfall.dat"); // List lines = Files.readAllLines(srcRailfallFile.toPath()); // String secondLine = lines.get(1); // return secondLine.split(" "); // } }