使用streamReader类读取c#中具有动态列数的文本文件

时间:2012-12-06 10:11:44

标签: c# winforms streamreader

 public class myRows
        {
            public decimal Col1 { get; set; }
            public decimal Col2 { get; set; }
            public decimal Col3 { get; set; }
            public decimal Col4 { get; set; }
            public decimal Col5 { get; set; }
            public decimal Col6 { get; set; }
            public string myDateTimeCol { get; set; }

            public myRows(string str)
            {
                var fields = str.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                Col1 = Convert.ToDecimal(fields[0]);
                Col2 = Convert.ToDecimal(fields[1]);
                Col3 = Convert.ToDecimal(fields[2]);
                Col4 = Convert.ToDecimal(fields[3]);
                Col5 = Convert.ToDecimal(fields[4]);
                Col6 = Convert.ToDecimal(fields[5]);
                myDateTimeCol = string.Format("{0} {1} {2} {3} {4}", fields[6], fields[7], fields[8], fields[9], fields[10]);
            }
        }

然后我读了我的LogFile

var rows = new List<myRows>();
var sr = new StreamReader(txtFileToImport.Text);

while (!sr.EndOfStream)
       {
          string s = sr.ReadLine();
           if (!String.IsNullOrEmpty(s.Trim()))
               {
                  rows.Add(new myRows(s));
                }
        }

sr.Close();
dataGridView_preView.DataSource = rows;

enter image description here

此代码面临的问题是,如果输入的LogFile有超过12列或更多列,我会得到索引超出范围异常

如果有,我可以重新考虑代码,使其处理任意数量列的LogFile。要处理的日志文件具有不同数量的列,我唯一的保证是日期列始终是所有情况下的最后一列。

2 个答案:

答案 0 :(得分:0)

试试这个:

public class myRows
        {
            public List<decimal> Cols = new List<decimal>();
            public string myDateTimeCol { get; set; }
            public string myVariableCols {
               get{
                  var sb = new StringBuilder();
                  for (var x = 0; x < Cols.length; x++){
                     sb.Append( Cols[x].ToString() );
                     if (x < Cols.length - 1) sb.Append("   ");
                  }
                  return sb.ToString();
               }
            }

            public myRows(string str)
            {
                var fields = str.Split(new[]{' '}, StringSplitOptions.RemoveEmptyEntries);
                int x;
                for (x = 0; x < fields.length-5;x++){
                   decimal d;
                   if (Decimal.TryParse(fields[x], out d)){
                      Cols.Add(d);
                   }
                }
                myDateTimeCol = string.Format("{0} {1} {2} {3} {4}", fields[x++], fields[x++], fields[x++], fields[x++], fields[x++]);
            }
        }

这适用于任何列大小(如果大于4)。 在您的数据网格中,您将只有两个数据绑定列:“myVariableCols”和“myDateTimeCol”。

答案 1 :(得分:0)

我有一个完全不同的方法,不使用任何列表。请原谅编码,这只是一个快速测试。

首先,我将使用DataTable。

public DataTable dt = new DataTable();

我从每行读入的数据将存储在Type String数组中。

public string[] data;

我们需要做的第一件事是确定数据文件中有多少列。下面我计算实例数,然后生成一个新的所需列数。

public void addcolumns()
        {

            using (StreamReader reader = new StreamReader(@"C:\DataColumnTest.txt"))
            {
                string s = reader.ReadLine();
                string[] col = s.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);


                foreach (var a in col)
                {
                    dt.Columns.Add(new DataColumn());
                }
            }
        }

接下来,在哪里要添加我们的DataTable行。我们的行数据中的列数应始终与DataTable中的列数相匹配,并且最初这样做的位置应该每次都有效: -

Public void addRows()
    {
        var sr = new StreamReader(@"C:\DataColumnTest.txt");

        while (!sr.EndOfStream)
        {
            string s = sr.ReadLine();
            if (!String.IsNullOrEmpty(s.Trim()))
            {
                data = null;
                data = s.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                dt.Rows.Add(data);
            }

        }

        sr.Close();
    }

所有我为这个快速示例所做的就是在表单Load中调用这些方法,然后为DataGrid添加数据源: -

 private void Form1_Load(object sender, EventArgs e)
        {

            addcolumns();
            addRows();
            dataGridView1.DataSource = dt;
        }

我知道会有更干净的方式来做这件事,但它确实有效,不像我见过的其他例子。

希望这有助于。

***编辑****

以下是我使用的数据以及结果。

enter image description here

enter image description here