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

C# 使用streamReader类读取c中具有动态列数的文本文件#,c#,winforms,streamreader,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 de

然后我像这样读我的日志文件

 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]);
            }
        }
var rows=new List();
var sr=新的StreamReader(txtFileToImport.Text);
而(!sr.EndOfStream)
{
字符串s=sr.ReadLine();
如果(!String.IsNullOrEmpty(s.Trim()))
{
行。添加(新的myRows);
}
}
高级关闭();
dataGridView_preView.DataSource=行;

这段代码面临的问题是,如果输入日志文件的列数超过12列或更多,则会出现索引超出范围异常

有没有办法,我可以重新因素的代码,使其处理任何日志文件与任何数量的列。要处理的日志文件有不同数量的列,我唯一能保证的是,在所有情况下,日期列始终是最后一列。

尝试以下方法:

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;
公共类myRows
{
public List Cols=新列表();
公共字符串myDateTimeCol{get;set;}
公共字符串myVariableCols{
得到{
var sb=新的StringBuilder();
对于(变量x=0;x
如果大于4,则这适用于任何列大小。
在datagrid中,您只有两个数据绑定列:“myVariableCols”和“myDateTimeCol”。

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

首先,我将使用一个数据表

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++]);
            }
        }
我从每一行读入的数据将存储在字符串类型的数组中

public DataTable dt = new DataTable();
我们需要做的第一件事是确定数据文件中有多少列。下面我计算实例的数量,然后根据所需的列数生成一个新的实例

public string[] data;
下一步,我们需要在数据表中添加行。行数据中的列数应始终与DataTable中的列数相匹配,并且在最初执行此操作时,每次都应起作用:-

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());
                }
            }
        }
对于这个快速示例,我所做的只是在form Load中调用这些方法,然后为DataGrid添加数据源:-

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();
    }
我知道会有更干净的方法来做到这一点,但它确实有效,不像我所看到的其他例子张贴

希望这有帮助

***编辑****

这是我使用的数据和结果


不用将行读入类,只需将它们读入
列表
,因此整个表存储在
列表
中,您是否也负责创建日志文件?如果没有-是否有任何规格?@mbx,我不负责创建日志文件。日志文件是由监控power generators.IC的专有软件系统创建的,然后我会使用一个列表,并组合成
DateTime.TryParse
的最后五个字段。如果您已经有了基于CSV的日志处理,那么简单的转换和使用已经测试过的代码也是一种选择。因为您没有任何规范,所以您所能做的就是收集任何新样本,自己构建/重新设计一个。这些select sample然后是您测试用例的一部分。我几乎在那里,但是日志文件中的所有可用列都作为一个myVariableCols列。是否有一种方法可以修改此代码并将这些列作为不同的字段/列返回。问题是,您不知道确切的列数。解决方法是将datagrid设置为autogeneratecolumns=“True”,然后将其绑定到动态数据源,动态数据源可能是一个列表;现在,您必须确保所有行(如列表)的长度相同,因此在数据绑定和向较短行添加空填充字符串之前,必须在行之间循环,直到它们达到集合中最长行的长度。我得到“Input array长于此表中的列数”异常。请检查您的代码,逐步通过AddColumns方法,错误在于构建列,我已经测试了它,它对我来说很好。请查看我的编辑。你可以看到它对我有效。如果你还被卡住了,现在就让我来。
 private void Form1_Load(object sender, EventArgs e)
        {

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