在文本文件中有以下数据:
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY XZHG03
2007-01-15 03:11:16 TT想导入到C#中来,无论是LISTIVEW或者DATAGRIDVIEW中都可以,请高手给段代码将以上数据按照下面格式导入:
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY
XZHG03 2007-01-15 03:11:16 TT
每行仅有4列数据尤其注意原始数据中的第二行,最后的XZHG03实际是第三行的第一列。请帮忙看一下,以下是部分代码:
string filepath=null;
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
filepath = this.openFileDialog1.FileName;
}
StreamReader sr = new StreamReader(filepath,Encoding.GetEncoding("GB2312"));
string s = sr.ReadToEnd();
sr.Close();
string []arr=s.Split(' ');
for (int i = 0; i < arr.Length; i++)
{
这里应该怎么写啊?麻烦给个详细的代码学习一下。
}
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY XZHG03
2007-01-15 03:11:16 TT想导入到C#中来,无论是LISTIVEW或者DATAGRIDVIEW中都可以,请高手给段代码将以上数据按照下面格式导入:
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY
XZHG03 2007-01-15 03:11:16 TT
每行仅有4列数据尤其注意原始数据中的第二行,最后的XZHG03实际是第三行的第一列。请帮忙看一下,以下是部分代码:
string filepath=null;
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
filepath = this.openFileDialog1.FileName;
}
StreamReader sr = new StreamReader(filepath,Encoding.GetEncoding("GB2312"));
string s = sr.ReadToEnd();
sr.Close();
string []arr=s.Split(' ');
for (int i = 0; i < arr.Length; i++)
{
这里应该怎么写啊?麻烦给个详细的代码学习一下。
}
这样是不够的,因为你这边还有换行符,所以这样换行符会被忽略掉
所以应该一行一行读取出数据再填充到数据源,最后再把数据源绑定到DataGridView,我这边是以DataGridView为例 private void button1_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
DataColumn dc = new DataColumn();
dc.ColumnName = "第一列";
dc.DataType = Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "第二列";
dc.DataType = Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "第三列";
dc.DataType = Type.GetType("System.String");
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "第四列";
dc.DataType = Type.GetType("System.String");
dt.Columns.Add(dc); string filepath = null; if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
filepath = this.openFileDialog1.FileName;
}
StreamReader sr = new StreamReader(filepath, Encoding.GetEncoding("GB2312")); while (sr.Peek() > 0) //逐行读取
{
string str = sr.ReadLine();
dt.Rows.Add(str.Split(' ')[0], str.Split(' ')[1], str.Split(' ')[2], str.Split(' ')[3]);
}
sr.Close(); this.dataGridView1.DataSource = dt;
}
这样即可把文件里的数据显示到dataGridView1中,不过我觉得你这边的二、三列(也就是时间)应该是合在一起的,所以这样的话应该是三列,可以在定义DataTable的时候去掉一列,并把
dt.Rows.Add(str.Split(' ')[0], str.Split(' ')[1], str.Split(' ')[2], str.Split(' ')[3]);
改成以下这句
dt.Rows.Add(str.Split(' ')[0], str.Split(' ')[1] + " " + str.Split(' ')[2], str.Split(' ')[3]);
即可。
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY XZHG03
2007-01-15 03:11:16 TT这样分隔符就不是用相同的空格来分割了,有是1个空格,有的是多个空格。并且在第二行中最后数据是第三行的头数据。能否读取一行,就限制为4列数据。然后加载到datagridview中呢?关键是数据加载的对齐问题。请根据我提供的数据进行测试。
上面这组数据中的分割是定死的吗?如果是的话,应该就比较好处理点,如果不是,那就有点费事了。
如果中间不是定死的一个空格,那就设法把它转成以单个空格区分,再处理也不是不行,就是感觉有点冗余了,更好的想法还需要考虑下。
string line = " XZHG02 2007-01-14 02:10:15 TY XZHG03";
string[] str = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string[] strs = File.ReadAllLines("C;\\temp.txt", Encoding.Default);
//用File类就可以搞定string[] strs = File.ReadAllText(path); //额不知道是不是这个方法,返回一个string[]数组//然后遍历数组,用Split() 根据“空格”在分开。//。。
如果追求高效,就应该一个字节一个字节的读,遇13和10忽略,依然追加入StringBuilder中,遇不是空格的字符,重新创建StringBuilder,四个一组,循环往复
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY XZHG03
2007-01-15 03:11:16 TT
整理成
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY
XZHG03 2007-01-15 03:11:16 TT中间有多少个空格没关系
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;
using System.Collections.Specialized;namespace test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
this.dataGridView1.Columns.Add("one", "one");
this.dataGridView1.Columns.Add("two", "two");
this.dataGridView1.Columns.Add("three", "three");
this.dataGridView1.Columns.Add("four", "four"); StringCollection strCol = ReadFileIntoStringCollection();
foreach (string curstr in strCol)
{
string[] str= curstr.Split(' ');
this.dataGridView1.Rows.Add(str[0], str[1], str[2], str[3]);
}
} // 把文件读入一个StringCollection类的实例, 此处需对文本文件中的数据进行处理.
StringCollection ReadFileIntoStringCollection()
{
StringCollection result = new StringCollection(); // StringCollection对象的每个元素包含文件中的一行文本
StreamReader sr = new StreamReader(@"C:\test.txt"); string exstring = string.Empty; // 保存每行数据中存在的多余字符
string curstring = string.Empty; // 保存当前行数据 string nextline;
while ((nextline = sr.ReadLine()) != null)
{
nextline = exstring.Equals(string.Empty) ? nextline : exstring + " " + nextline; // 将每行多余的字符添加至当前行
exstring = curstring = string.Empty; // 清空临时数据 while (nextline[0] == ' ') // 如果字符串的启始处有空白符, 则移除
nextline = nextline.Substring(1, nextline.Length - 1); string[] strcol = nextline.Split(' ');
for (int i = 0; i < strcol.Length; i++)
{
if (strcol[i].Equals(string.Empty)) continue; // 如果字符为空, 则跳过 if (curstring.Split(' ').Length < 4)
{
curstring = curstring.Equals(string.Empty) ? strcol[i] : curstring + " " + strcol[i];
}
else
exstring = strcol[i];
}
result.Add(curstring); // 把字符串添加到集合中
}
sr.Close();
return result;
}
}
}
如上所示, 代码中的 ReadFileIntoStringCollection 函数用于格式化文本文件中的数据.
文本文件保存在 C:\test.txt 中, 具体内容为:
XZHG01 2007-01-14 01:00:12 SU
XZHG02 2007-01-14 02:10:15 TY XZHG03
2007-01-15 03:11:16 TT
public void Test()
{
System.IO.StreamReader reader = new System.IO.StreamReader(@"C:\test.txt", Encoding.Default); string[] fields = new string[4]; //字段缓存 int index = 0; //当前字段索引 int code = 0; //当前读取字符 System.Text.StringBuilder buffer = new StringBuilder(); char chr = '\0'; //存放上次读取的字符 while (-1 != (code = reader.Read()))
{
if (index == 4) //字段已满,创建行
{
CreateDataRow(fields);
index = 0;
} if (code == 13 || code == 10 || code == 9) //视回车换行TAB为空格对待
code = 32; if (code == 32 && ' ' == chr) //忽略多余空格
continue; chr = (char)code; if (' ' == chr)//遇空格,创建上一字段内容
{
fields[index] = buffer.ToString();
buffer = new StringBuilder();
index++;
}
else
{
buffer.Append(chr);
}
} CreateDataRow(fields, index); reader.Close();
}
private void CreateDataRow(string[] fields, int nCount)
{
if (nCount == 4)
{
//只处创建row,代码从略
}
//以下重置缓存
for (int i = 0; i < fields.Length; i++)
{
fields[i] = "";
} }
while (sr.Peek() > 0)
{
string[] str = sr.ReadLine().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
if (str.Length > 4) //若超四列,dt要新添加两行
{
DataRow dr1 = dt.NewRow();
DataRow dr2 = dt.NewRow();
dr1["第一列"] = str[0];
dr1["第二列"] = str[1];
dr1["第三列"] = str[2];
dr1["第四列"] = str[3];
dr2["第一列"] = str[4]; //最后一列数据则添加到新行
dt.Rows.Add(dr1);
dt.Rows.Add(dr2);
}
else if (str.Length == 4) //正常情况下是四列
{
DataRow dr = dt.NewRow();
dr["第一列"] = str[0];
dr["第二列"] = str[1];
dr["第三列"] = str[2];
dr["第四列"] = str[3];
dt.Rows.Add(dr);
}
else
//若不足四列,说明此时dt的最后一行只有第一列被填充,
//只要继续填充后三列数据即可
{
dt.Rows[dt.Rows.Count - 1]["第二列"] = str[0];
dt.Rows[dt.Rows.Count - 1]["第三列"] = str[1];
dt.Rows[dt.Rows.Count - 1]["第四列"] = str[2];
}
}
其余代码和我2楼的代码一样,这边改下while循环体代码,这样便可达到你要的效果。不过我还是希望可以先手动整理一下文件数据格式,就是保证每行都是四列数据,中间多少个空格没关系。就因为每行数据不整齐(有的3列,有的4列,有的5列)而导致代码量的增加(从我2楼和这边的代码对比很明显就可以看出来),伤神着呢,呵呵:)