繁体   English   中英

忽略CSV文件C#中的行

[英]Ignore lines in CSV file c#

CSV文件有问题。 我想跳过此时不相关的前几行,并开始处理实际数据所在的文件。是否可以跳过所有标头?

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace bike
{
    public partial class Form1 : Form
    {
        public Form1()
        {

            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)
        {

            var col1 = new List<string>();
            var col2 = new List<string>();
            var col3 = new List<string>();
            var col4 = new List<string>();

            var Column1 = col1.Select<string, int>(q => Convert.ToInt32(q));
            var Column2 = col2.Select<string, int>(q => Convert.ToInt32(q));
            var Column3 = col3.Select<string, int>(q => Convert.ToInt32(q));
            var Column4 = col4.Select<string, int>(q => Convert.ToInt32(q));



            dataGridView1.Columns.Add("col1", "Heart Rate");
            dataGridView1.Columns.Add("col2", "Speed");
            dataGridView1.Columns.Add("col3", "Power");
            dataGridView1.Columns.Add("col4", "Altitude");



            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
                {

                    int row = 0;
                    string line;

                    bool isInHRData = false;

                    while ((line = sr.ReadLine()) !=null)
                    {
                        if (!isInHRData)
                        {
                            if (line != "[HRData]")
                                continue;
                            isInHRData = true;
                            continue;
                        }

                        else if (line.StartsWith("[") && line.EndsWith("["))
                            break;

                        string[] columns = line.Split('\t');
                        if (columns.Length > 0)
                            col1.Add(columns[0]);
                        if (columns.Length > 1)
                            col2.Add(columns[1]);
                        if (columns.Length > 2)
                            col3.Add(columns[2]);
                        if (columns.Length > 3)
                            col4.Add(columns[3]);



                        /*col1.Add(columns[0]);
                        col2.Add(columns[1]);
                        col3.Add(columns[2]);
                        col4.Add(columns[3]);
                         */

                        dataGridView1.Rows.Add();
                        for (int i = 0; i < columns.Length; i++)
                        {
                            dataGridView1[i, row].Value = columns[i];
                        }
                        row++; 
                    }

                    int maxSpeed = Column2.Max();
                    maxSpeed = maxSpeed / 10;
                    string MaxSpeed = Convert.ToString(maxSpeed);
                    textBox1.Text = MaxSpeed;

                    double aveSpeed = Column2.Average();
                    aveSpeed = aveSpeed / 10;
                    aveSpeed = Math.Round(aveSpeed, 0);
                    string AveSpeed = Convert.ToString(aveSpeed);
                    textBox2.Text = AveSpeed;

                    double aveHeart = Column1.Average();
                    aveHeart = Math.Round(aveHeart, 0);
                    string AveHeart = Convert.ToString(aveHeart);
                    textBox3.Text = AveHeart;

                    int maxHeart = Column1.Max();
                    string MaxHeart = Convert.ToString(maxHeart);
                    textBox4.Text = MaxHeart;

                    int minHeart = Column1.Min();
                    string MinHeart = Convert.ToString(minHeart);
                    textBox5.Text = MinHeart;

                    double avePower = Column3.Average();
                    avePower = Math.Round(avePower, 0);
                    string AvePower = Convert.ToString(avePower);
                    textBox6.Text = AvePower;

                    int maxPower = Column3.Max();
                    string MaxPower = Convert.ToString(maxPower);
                    textBox7.Text = MaxPower;

                    double aveAltitude = Column4.Average();
                    aveAltitude = Math.Round(aveAltitude, 0);
                    string AveAltitude = Convert.ToString(aveAltitude);
                    textBox8.Text = AveAltitude;

                    int maxAltitude = Column4.Max();
                    string MaxAltitude = Convert.ToString(maxAltitude);
                    textBox9.Text = MaxAltitude;


                }
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

以及一个CSV文件的示例(HRData位是我需要显示的唯一文件,因此我想忽略其余所有文件):

[Params]
Version=106
Monitor=34
SMode=111000100
Date=20101110
StartTime=13:47:00.0
Length=02:07:41.7
Interval=5
Upper1=150
Lower1=140
Upper2=0
Lower2=0
Upper3=180
Lower3=177
Timer1=00:00:00.0
Timer2=00:00:00.0
Timer3=00:00:00.0
ActiveLimit=0
MaxHR=195
RestHR=48
StartDelay=0
VO2max=54
Weight=0

[Note]

[IntTimes]
00:01:23.7  139 0   118 139
0   0   0   290 75  69
0   0   0   0   0
0   444 0   70  0   0
0   0   0   0   0   0
00:30:51.4  157 0   145 158
0   0   0   372 133 2
0   0   0   0   0
0   16020   0   90  0   0
0   0   0   0   0   0
01:04:46.0  148 0   146 157
0   0   0   245 118 11
0   0   0   0   0
0   32000   0   80  0   0
0   0   0   0   0   0
01:34:33.7  138 0   144 152
0   0   0   336 116 32
0   0   0   0   0
0   46524   0   70  0   0
0   0   0   0   0   0
02:06:40.4  145 0   144 160
0   0   0   253 130 60
0   0   0   0   0
0   60432   0   60  0   0
0   0   0   0   0   0
02:07:41.7  119 0   129 145
0   0   0   0   75  55
0   0   0   0   0
0   60791   0   60  0   0
0   0   0   0   0   0

[IntNotes]
1   
2   
3   
4   
5   
6   

[ExtraData]

[LapNames]
1   0   
2   0   
3   0   
4   0   
5   0   
6   0   

[Summary-123]
7660    0   820 5995    845 0
195 150 140 48
7660    0   820 5995    845 0
195 0   0   48
0   0   0   0   0   0
195 0   0   48
0   1532

[Summary-TH]
7660    0   7660    0   0   0
195 0   0   48
0   1532

[HRZones]
195
176
156
137
117
98
0
0
0
0
0

[SwapTimes]

[Trip]
607
329
7661
15
70
286
494
4720

[HRData]
91  161 0   64
91  159 0   64
98  225 56  63
105 260 68  63
106 183 70  63
101 52  55  63
104 119 29  63
110 153 32  63
118 161 42  64
124 113 43  65
123 77  38  66
125 189 32  66
129 248 64  66
134 272 73  66
137 271 75  67
137 270 73  67

试试这个代码:

...
int row = 0;
string line;
bool isInHRData = false;

while ((line = sr.ReadLine()) !=null)
{
    if (!inHRData)
    {
         if (line == "[HRData]")
              isInHRData = true;
         continue;
    } 
    ....

如果还有AFTER HRData另一部分,请添加以下代码:

...
int row = 0;
string line;
bool isInHRData = false;

while ((line = sr.ReadLine()) !=null)
{
    if (!inHRData)
    {
         if (line == "[HRData]")
              isInHRData = true;
         continue;
    } 
    else if (line.StartsWith("[") && line.EndsWith("[")) // This criteria can be mucht better, checking for words, etc. but you in essence this will work.
        break;
    ....

对于IndexOutOfRangeException:

string[] columns = line.Split('\t');
if (columns.Length > 0)
     col1.Add(columns[0]);
if (columns.Length > 1)
     col2.Add(columns[1]);
if (columns.Length > 2)
     col3.Add(columns[2]);
if (columns.Length > 3)
     col4.Add(columns[3]);

由于其余代码中还存在其他小错误,因此我为您提供了重构功能。 这个例子没有重构,它是完全重写的。 我将逻辑与用户界面分开。 这总是一件好事。 它为您准备了将逻辑迁移到其他类型的应用程序(例如WPF的Web应用程序)的过程。

该代码完全基于职责分离:

  • HRData:实体,代码的主要参与者。 您的基本数据。 实体比整数数组要好,因为属性赋予了更多含义。
  • HRDataExtensions:负责进行计算的统计方法。
  • HRDataReader:负责读取文件并将其读入HRData列表。

使用此HRData列表,您可以填充UI表单。

public class HRData
{
    public int? HeartRate
    {
        get;
        set;
    }
    public int? Speed
    {
        get;
        set;
    }
    public int? Power
    {
        get;
        set;
    }
    public int? Altitude
    {
        get;
        set;
    }

    public override string ToString()
    {
        return String.Format("Heart rate={0}, Speed={1}, Power={2}, Altitude={3}", HeartRate, Speed, Power, Altitude);
    }
}

public static class HRDataExtensions
{
    static private int? CalculateInt32(this IEnumerable<HRData> data, Func<HRData, int?> valueSelector, Func<IEnumerable<int?>, int?> aggregation)
    {
        List<int?> list = new List<int?>();
        list.AddRange(data.Select(valueSelector));
        return aggregation(list);
    }

    static private int? CalculateDouble(this IEnumerable<HRData> data, Func<HRData, int?> valueSelector, Func<IEnumerable<int?>, double?> aggregation)
    {
        List<int?> list = new List<int?>();
        list.AddRange(data.Select(valueSelector));
        double? result = aggregation(list);
        return (result == null) ? null : (int?)Math.Round(result.Value);
    }

    static public int? MinimumHeartRate(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.HeartRate, Enumerable.Min);
    }

    static public int? MaximumHeartRate(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.HeartRate, Enumerable.Max);
    }

    static public int? AverageHeartRate(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.HeartRate, Enumerable.Average);
    }

    static public int? MinimumSpeed(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Speed, Enumerable.Min);
    }

    static public int? MaximumSpeed(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Speed, Enumerable.Max);
    }

    static public int? AverageSpeed(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.Speed, Enumerable.Average);
    }

    static public int? MinimumPower(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Power, Enumerable.Min);
    }

    static public int? MaximumPower(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Power, Enumerable.Max);
    }

    static public int? AveragePower(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.Power, Enumerable.Average);
    }

    static public int? MinimumAltitude(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Altitude, Enumerable.Min);
    }

    static public int? MaximumAltitude(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Altitude, Enumerable.Max);
    }

    static public int? AverageAltitude(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.Altitude, Enumerable.Average);
    }
}

public static class HRDataReader
{
    static private int? ConvertValue(string[] values, int index)
    {
        if (index >= values.Length)
            return null;
        int value;
        if (int.TryParse(values[index], out value))
            return value;
        return null;
    }

    static public IList<HRData> Read(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            throw new ArgumentNullException("fileName");
        using (StreamReader sr = new StreamReader(fileName))
        {
            string line;

            // First: Skip to the correct section.
            while ((line = sr.ReadLine()) != null)
                if (line == "[HRData]")
                    break;

            // Now: Read the HRData
            List<HRData> data = new List<HRData>();
            while ((line = sr.ReadLine()) != null)
            {
                if (line.StartsWith("[") && line.EndsWith("]"))
                    break;
                line = line.Trim().Replace("\t", " "); // Remove all tabs.
                while (line.Contains("  ")) // Remove all duplicate spaces.
                    line = line.Replace("  ", " ");
                string[] values = line.Split(' '); // Split the line up.
                data.Add(new HRData
                {
                    HeartRate = ConvertValue(values, 0),
                    Speed = ConvertValue(values, 1),
                    Power = ConvertValue(values, 2),
                    Altitude = ConvertValue(values, 3)
                });
            }
            return data;
        }
    }
}

编辑

现在,您可以像这样调整代码:

    private void button1_Click(object sender, EventArgs e)
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            dataGridView1.Rows.Clear();
            dataGridView1.Columns.Clear();

            IList<HRData> data = HRDataReader.Read(openFileDialog1.FileName);

            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "HeartRate", HeaderText = "Heart rate", DataPropertyName = "HeartRate" });
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Speed", HeaderText = "Speed", DataPropertyName = "Speed" });
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Power", HeaderText = "Power", DataPropertyName = "Power" });
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Altitude", HeaderText = "Altitude", DataPropertyName = "Altitude" });

            dataGridView1.DataSource = data;

            label1.Text = data.MaximumAltitude().ToString();

            textBox1.Text = data.MaximumSpeed().ToString();
            textBox2.Text = data.AverageSpeed().ToString();
            textBox3.Text = data.AverageHeartRate().ToString();
            textBox4.Text = data.MaximumHeartRate().ToString();
            textBox5.Text = data.MinimumHeartRate().ToString();
            textBox6.Text = data.AveragePower().ToString();
            textBox7.Text = data.MaximumPower().ToString();
            textBox8.Text = data.AverageAltitude().ToString();
            textBox9.Text = data.MaximumAltitude().ToString();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM