2013-04-28 69 views
0

我遇到了CSV文件的問題。我想跳過目前不相關的前幾行,並開始處理實際數據所在的文件。是否有跳過所有標題的方法?忽略CSV文件中的行c#

這裏是我的代碼:

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 

回答

3

試試這個代碼:如果有AFTER HRData另一部分

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

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

,添加以下代碼:

... 
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]); 
+0

嘗試過了,沒有工作。在col2.Add(columns [1])行上出現IndexOutOfRangeException; – user2047427 2013-04-28 14:24:28

+0

'isInHRData = true;繼續;還有一個繼續跳過'[HRData]'行。並且''line.EndsWith(「]」))' – Corak 2013-04-28 14:26:58

+0

@Corak:謝謝! – 2013-04-28 14:27:36

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(); 
     } 
    } 
+0

我想了解代碼,我掙扎了一下。從來沒有像分開它那樣真正做到這一點。我必須打電話給他們才能在桌上顯示它嗎? – user2047427 2013-04-28 16:57:47

+0

提出您的問題,這是網站的目的。 – 2013-04-28 16:59:33

+0

我猜這是一個面向對象的方式。我是否必須在我的命名空間下鏈接並調用它們的類? – user2047427 2013-04-28 17:02:21