关于使用 C# 处理水位数据多种格式的统一转换
- 1、前言
- 2、水位数据的多种格式
- 3、水位数据多种格式的统一转换程序展示
- 4、水位数据多种格式的统一转换 C# 代码
- 4.1、声明引用命名空间
- 4.2、多种格式的统一转换 C# 代码
- 4.3、多种格式的统一转换 C# 代码,文件输出保存
1、前言
YAC9900 水位雨量存储器有很多固件版本,SD 卡存储的数据存在多种数据格式。统一转换数据格式精简优化编程代码。
同时多种版本的文件在打开对话框进行多选文件,合并所有月份的数据,整合数据文件。
2、水位数据的多种格式
因 YAC9900 版本不同,SD卡存储数据格式有四种情况
1、日期、时间、水位(Z:)、雨量(PT:)、电压(VT:)"2024/03/31 23:55:00 Z:28.29 PT:976.5 VT:12.91",2、数据个数、日期、时间、水位(Z:)、雨量(PT:)、电压(VT:)"num1120 2024/07/02 09:45:00 Z:34.94 PT:269.5 VT:14.24",3、日期、时间、水位、雨量、电压"2024/04/30 23:55:00 29.179 277.5 12.71",4、每30分钟记录水位,其它无水位:"2021/01/01 00:00:00 Z:27.37 PT:0 VT:11.31","2021/01/01 00:05:00 PT:0 VT:11.33","2021/01/01 00:10:00 PT:0 VT:11.36","2021/01/01 00:15:00 PT:0 VT:11.30","2021/01/01 00:20:00 PT:0 VT:11.31","2021/01/01 00:25:00 PT:0 VT:11.32","2021/01/01 00:30:00 Z:27.36 PT:0 VT:11.23",
从上面数据可以看出,以空格分解;
设定以第一列为日期,则后面依次是:第二列为时间,则第三列为水位,第四列为雨量,第五列为设备电压。
3、水位数据多种格式的统一转换程序展示
4、水位数据多种格式的统一转换 C# 代码
4.1、声明引用命名空间
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;
4.2、多种格式的统一转换 C# 代码
Array.Sort(FilesList);//打开对话框选择多个 SD 卡数据文件后,进行文件字符串排序//Console.WriteLine("文件列表: " + String.Join("\r\n", x));string FilePathName = FilesList[0];int Pos = FilePathName.LastIndexOf(".");List<string> WaterLevelAndRain = new List<string>();foreach (string FileStr in FilesList){using (StreamReader sr = new StreamReader(FileStr)){string line;while ((line = sr.ReadLine()) != null){WaterLevelAndRain.Add(line);//将多文件的所有数据添加到LIST列表}}}//Console.WriteLine("原始列表: " + String.Join("\r\n", WaterLevelAndRain));WaterLevelAndRain.RemoveAll(str => string.IsNullOrEmpty(str));//删除LIST空值WaterLevelAndRain = WaterLevelAndRain.Distinct().ToList();//删除LIST重复项,即删除 行数据 重复值string[] WR = WaterLevelAndRain.ToArray();//转换为数组WaterLevelAndRain.Clear();//清除列表,,释放内存空间int WRL = WR.Length;//Console.WriteLine(WR.Length);DateTime[] DataDT = new DateTime[WRL];Double[] WL = new double[WRL];Double[] RL = new double[WRL];for (int i = 0; i < WRL; i++){string[] split = WR[i].Split(',', ' ', '\t');//以逗号、空格、制表符分裂int num1 = split[0].IndexOf("num");int num2;if (num1 == 0)//前有num,新YAC9900前有数据个数标志 num{DataDT[i] = DateTime.Parse(split[1] + " " + split[2]);//整合为时间序列num2 = split[3].IndexOf(":");//水位有前缀的按冒号分裂if (num2 > 0){int num3 = split[3].IndexOf("Z:");if (num3 == -1)//数据无水位: {WL[i] = -20000;//假定为无效水位,没有正常读取传感器的水位int index = split[3].IndexOf(':') + 1;string R = split[3].Substring(index);RL[i] = Convert.ToDouble(R);}else{int index = split[3].IndexOf(':') + 1;string W = split[3].Substring(index);index = split[4].IndexOf(':') + 1;string R = split[4].Substring(index);WL[i] = Convert.ToDouble(W);RL[i] = Convert.ToDouble(R);}}else{WL[i] = Convert.ToDouble(split[3]);RL[i] = Convert.ToDouble(split[4]);}}else if (num1 == -1)//前无num{int test = split[0].IndexOf('/');if (test > 4)//旧YAC_BUG,在日期数据前出现文件名{split[0] = split[0].Substring(test - 4);}DataDT[i] = DateTime.Parse(split[0] + " " + split[1]);num2 = split[2].IndexOf(":");if (num2 > 0){int num3 = split[2].IndexOf("Z:");if (num3 == -1)//无水位: {WL[i] = -20000;//假定为无效水位int index = split[2].IndexOf(':') + 1;string R = split[2].Substring(index);RL[i] = Convert.ToDouble(R);}else{int index = split[2].IndexOf(':') + 1;string W = split[2].Substring(index);index = split[3].IndexOf(':') + 1;string R = split[3].Substring(index);WL[i] = Convert.ToDouble(W);RL[i] = Convert.ToDouble(R);}}else{WL[i] = Convert.ToDouble(split[2]);RL[i] = Convert.ToDouble(split[3]);}}//Console.WriteLine(String.Join(",", split));//Console.WriteLine(DataDT[i]);//Console.WriteLine(WL[i]);//Console.WriteLine(RL[i]);//Console.WriteLine();}
4.3、多种格式的统一转换 C# 代码,文件输出保存
string StartDate = DataDT[0].ToString("yyyy年MM月dd日", CultureInfo.InvariantCulture);//获取数据的开始日期string EneDate = DataDT[WRL - 1].ToString("yyyy年MM月dd日", CultureInfo.InvariantCulture);//获取数据的结束日期string RainFilePathName = FilePathName.Substring(0, Pos) + "-" + StartDate + "至" + EneDate + "雨量" + FilePathName.Substring(Pos);string WaterLevelFilePathName = FilePathName.Substring(0, Pos) + "-" + StartDate + "至" + EneDate + "水位" + FilePathName.Substring(Pos);FileStream SaveWLFS = new FileStream(WaterLevelFilePathName, FileMode.Create);StreamWriter SWWLFS = new StreamWriter(SaveWLFS, Encoding.GetEncoding("gb2312"));FileStream SaveRAFS = new FileStream(RainFilePathName, FileMode.Create);StreamWriter SWRAFS = new StreamWriter(SaveRAFS, Encoding.GetEncoding("gb2312"));for (int i = 0; i < WRL; i++){string OutWL = "";string OutRA = "";if (i == 0 && WL[i] != -20000){OutWL = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + ((int)(WL[i] * 100)).ToString("000000");OutRA = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + RL[i].ToString("0000.0");}else if (WL[i] != -20000 && DataDT[i] != DataDT[i - 1]){OutWL = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + ((int)(WL[i] * 100)).ToString("000000");OutRA = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + RL[i].ToString("0000.0");}else if (i == WRL - 1 && WL[i] == -20000)//最后一个是-20000{OutWL = "";OutRA = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + RL[i].ToString("0000.0");}else if (i > 0 && WL[i] == -20000 && WL[i + 1] != -20000 && WL[i - 1] != -20000 && Math.Abs(WL[i + 1] - WL[i - 1]) <= 0.03 && DataDT[i] != DataDT[i - 1]){WL[i] = (WL[i + 1] + WL[i - 1]) / 2;OutWL = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + ((int)(WL[i] * 100)).ToString("000000");OutRA = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + RL[i].ToString("0000.0");}else{OutWL = "";OutRA = DataDT[i].ToString("yyyy/MM/dd HH:mm ", CultureInfo.InvariantCulture) + RL[i].ToString("0000.0");}if (OutWL != ""){SWWLFS.WriteLine(OutWL);}SWRAFS.WriteLine(OutRA);OutWL = "";OutRA = "";//Console.WriteLine(OutWL);//Console.WriteLine();// OutSTR = DataDT[i].ToString("yy/MM/dd hh:mm ", CultureInfo.InvariantCulture) + RL[i].ToString("0000.0");}SWWLFS.Flush();//关闭打开的文件,释放内存空间SWWLFS.Close();SWRAFS.Flush();SWRAFS.Close();Array.Clear(DataDT, 0, WRL);//关闭数组,释放内存空间Array.Clear(WL, 0, WRL);Array.Clear(RL, 0, WRL);