关于使用 C# 处理水位数据多种格式的统一转换

关于使用 C# 处理水位数据多种格式的统一转换

1、前言

YAC9900 水位雨量存储器有很多固件版本,SD 卡存储的数据存在多种数据格式。统一转换数据格式精简优化编程代码。
同时多种版本的文件在打开对话框进行多选文件,合并所有月份的数据,整合数据文件。

2、水位数据的多种格式

因 YAC9900 版本不同,SD卡存储数据格式有四种情况

bash 复制代码
        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、声明引用命名空间

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;

4.2、多种格式的统一转换 C# 代码

csharp 复制代码
                 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# 代码,文件输出保存

csharp 复制代码
                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);
相关推荐
阿乾之铭2 分钟前
Spring Boot框架中的IO
java·spring boot·log4j·1024程序员节
百流14 分钟前
Pyspark中pyspark.sql.functions常用方法(4)
1024程序员节
qq210846295317 分钟前
【Ubuntu】Ubuntu22双网卡指定网关
1024程序员节
YueTann35 分钟前
APS开源源码解读: 排程工具 optaplanner II
1024程序员节
kinlon.liu43 分钟前
安全日志记录的重要性
服务器·网络·安全·安全架构·1024程序员节
爱编程— 的小李1 小时前
开关灯问题(c语言)
c语言·算法·1024程序员节
是程序喵呀1 小时前
Uni-App-02
uni-app·vue·1024程序员节
A_aspectJ2 小时前
Spring 框架中都用到了哪些设计模式?
spring·设计模式·1024程序员节
双子座断点2 小时前
QT 机器视觉 (3. 虚拟相机SDK、测试工具)
qt·1024程序员节
20岁30年经验的码农2 小时前
爬虫基础
1024程序员节