忽略CSV文件中的行c#

时间:2013-04-28 14:09:44

标签: c# csv

我的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

2 个答案:

答案 0 :(得分:3)

试试这段代码:

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

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

如果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]);

答案 1 :(得分:1)

由于其他代码中出现的其他小错误,我建议你重构。这个例子没有重构,它完全被重写。我从用户界面中分离出逻辑。这总是一件好事。它使您准备将逻辑迁移到其他类型的应用程序,如WPF的Web应用程序。

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

  • HRData:实体,代码的主要播放器。你的基本数据。实体优于int数组,因为属性提供了更多的含义。
  • 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();
        }
    }