C#读取测力仪CSV数据:列表与文件列长度不符问题排查
我用C#编写代码读取测力仪导出的CSV数据,计划将每列数据存入对应的List,但实际发现CSV单列有近118000条数据,生成的List却仅包含14365条。以下是我的代码:
读数类代码
public class ReadingClassSample { public double Time; public double Ax; public double Ay; public double Az; public double Bx; public double By; public double Bz; public double Cx; public double Cy; public double Cz; public double Dx; public double Dy; public double Dz; public ReadingClassSample() {} public ReadingClassSample(string[] vals) { try { Double.TryParse(vals[0], out Time); Double.TryParse(vals[1], out Ax); Double.TryParse(vals[2], out Ay); Double.TryParse(vals[3], out Az); Double.TryParse(vals[6], out Bx); Double.TryParse(vals[5], out By); Double.TryParse(vals[6], out Bz); Double.TryParse(vals[7], out Cx); Double.TryParse(vals[8], out Cy); Double.TryParse(vals[9], out Cz); Double.TryParse(vals[10], out Dx); Double.TryParse(vals[11], out Dy); Double.TryParse(vals[12], out Dz); } catch { MessageBox.Show("There was an error parsing the data into a double."); } } }
CSV读取代码
public void ReadLCCSVFile(string samplePath) { StreamReader sampleReader; List<ReadingClassSample> lcOutputList = new List<ReadingClassSample>(); List<double> AxList = new List<double>(); List<double> AyList = new List<double>(); List<double> AzList = new List<double>(); List<double> BxList = new List<double>(); List<double> ByList = new List<double>(); List<double> BzList = new List<double>(); List<double> CxList = new List<double>(); List<double> CyList = new List<double>(); List<double> CzList = new List<double>(); List<double> DxList = new List<double>(); List<double> DyList = new List<double>(); List<double> DzList = new List<double>(); if (File.Exists(samplePath)) { sampleReader = new StreamReader(File.OpenRead(samplePath)); while (!sampleReader.EndOfStream) { var line = sampleReader.ReadLine(); string[] values = line.Split(','); ReadingClassSample temp = new ReadingClassSample(values); sampleOutputList.Add(temp); } AxList.Add(sampleOutputList[ii].Ax); AyList.Add(sampleOutputList[ii].Ay); AzList.Add(sampleOutputList[ii].Az); BxList.Add(sampleOutputList[ii].Bx); ByList.Add(sampleOutputList[ii].By); BzList.Add(sampleOutputList[ii].Bz); CxList.Add(sampleOutputList[ii].Cx); CyList.Add(sampleOutputList[ii].Cy); CzList.Add(sampleOutputList[ii].Cz); DxList.Add(sampleOutputList[ii].Dx); DyList.Add(sampleOutputList[ii].Dy); DzList.Add(sampleOutputList[ii].Dz); SampleAxList = AxList; SampleAyList = AyList; SampleAzList = AzList; SampleBxList = BxList; SampleByList = ByList; SampleBzList = BzList; SampleCxList = CxList; SampleCyList = CyList; SampleCzList = CzList; SampleDxList = DxList; SampleDyList = DyList; SampleDzList = DzList; } }
核心原因分析
1. 变量名混淆导致数据未正确存储
你在方法内部定义了lcOutputList用于存储本次读取的所有数据,但在循环添加时却写了sampleOutputList.Add(temp);——如果sampleOutputList是类的成员变量,那它保存的很可能是之前读取的旧数据(刚好14365条),而本次读取的118000条数据根本没存入lcOutputList,后续转存单列List时又错误使用了sampleOutputList,最终导致List只有旧数据的长度。
2. 缺失遍历循环,数据未全部转存
读取完CSV所有行后,你将对象数据转存到单列List的代码没有循环包裹,而且ii变量未定义——这段代码要么编译报错,要么只会执行一次,根本不会把所有数据都添加到单列List中。正常应该用foreach遍历目标列表,把每一行的数据依次添加到对应List:
foreach (var item in sampleOutputList) { AxList.Add(item.Ax); AyList.Add(item.Ay); AzList.Add(item.Az); // ...其他列的添加逻辑 }
3. CSV解析逻辑不严谨(次要原因)
直接用line.Split(',')处理CSV存在隐患:如果某列数据包含逗号(比如带引号的字段"123,456"),拆分后会得到错误的数组长度,导致构造函数中索引越界。虽然有try-catch捕获异常,但会跳过该行数据,不过这种情况只会导致少量数据丢失,不会出现从118000到14365的大幅减少。
4. 构造函数的索引错误(不影响数量但需修正)
注意到构造函数中Bx和Bz都用了vals[6],By用了vals[5],这明显是索引错位,会导致Bx、By、Bz的数据值错误,需要根据CSV的实际列顺序修正索引。
内容的提问来源于stack exchange,提问作者LoonieToonie

