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;
}