将datatable中的数据写成txt文件的速度问题?? 50分 在线等!!
将datatable中的数据写成txt文件的速度问题??datatable中保存了大量的数据,大概90多万条。现在用下面的代码将其写成txt文件。发现速度其慢无比。看代码:
private void WriteTxt(DataTable tb)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamWriter sr;
if (File.Exists(saveFileDialog1.FileName)) //如果文件存在,则创建File.AppendText对象
{
sr = File.AppendText(saveFileDialog1.FileName);
}
else //如果文件不存在,则创建File.CreateText对象
{
sr = File.CreateText(saveFileDialog1.FileName);
}
foreach (DataRow dr in tb.Rows)
{
sr.WriteLine(dr[0].ToString() + "\t" + dr[1].ToString() + "\t" + dr[2].ToString() + "\t" + dr[3].ToString() + "\t" + dr[4].ToString() + "\t" + dr[5].ToString() + "\t" + dr[6].ToString() + "\t" + dr[7].ToString());
}
sr.Close();
}
}
请教高手应该怎么才能提高效率呢??? --------------------编程问答-------------------- 估算一下90万条保存成文本数据有多大?
使用异步I/O --------------------编程问答-------------------- 将近30m。 --------------------编程问答-------------------- 在把上面的问题解释一下,程序生成90多万条记录保存在datatable里面,现在我想把这些记录保存成txt文件,上面的代码已经可以实现,只是现在的效率非常的低,90多万条数据用了大概5-8分钟的时间才保存好,其间cpu占用率一直是100% ,保存完成后就提示虚拟内存不足。我的机器物理内存1.5g 虚拟内存2g。
1楼的能不能具体说说怎么用异步io来实现,还有其他提高效率的方法吗? --------------------编程问答-------------------- 建议不要使用DataTable,使用DataReader吧,读一行数据就往文本文件里写一行 --------------------编程问答-------------------- fangxinggood 数据时实时生成的,不是从数据库中读出来的。也就是说只有生成好了才能保存,这怎么使用DataReader。 --------------------编程问答-------------------- 数据时实时生成
那可不可以生成一点就保存一点,而不是等都生成完了,一下全部保存。。 --------------------编程问答-------------------- 那换句话说吧,DataTable是怎么创建出来的?
建议把导出时机再提前一些,往DataTable.Rows.Add的时候就可以往文本文件里输出了。
再换个问法,DataTable的存在只是为了输出文本文件?还是要进行别的处理?(比如:需要拿来显示用) --------------------编程问答-------------------- 恩。。保存成XML比较好把 --------------------编程问答-------------------- DataTable是内存中的表,90万这样的数量级别先不考虑输出的效率,内存也受不了。
最好是考虑一下DataTable这个数据容器是否需要。
或者是考虑当DataTable数量达到一定级别的时候就输出一下。
如果是一次取入,一次输出的话,用多线程也解决不了内存溢出的问题 --------------------编程问答-------------------- fangxinggood 是需要拿来处理的,且要显示出来。生成这90多w条记录并在datagridview中显示出来大概需要2-3分钟的时间,这个时间也是难以忍受的。但是也一直没有找到好的解决方法。保存着90多万条记录用的时间就更长了 ,实在难以忍受了。生成时用xml文件来存放会比较快些吗?理论上数据量都是一样的呀? --------------------编程问答-------------------- sr.AutoFlush = true;
这样就可以不用到了最后才一次写入了。
试试看。
不过你实时生成90万条记录时间就会很长,你还是生成一条就往文件流里写吧。 --------------------编程问答-------------------- XML不会更快。
关于显示,建议使用分页。。。客户不可能一口气看90w条数据吧。。。
保存记录的话,最好是DataTable生成中就开始处理输出。。。
你这样的需求没有什么办法了。。。
应该建议客户固定文件大小,分页显示。这样能好一些。
--------------------编程问答-------------------- 1 最好不要一次取出所有数据,内存受不了,取一部分先写出来再取.显示也是一样,你一个页面不可能显示这么多数据,所以不需要先取出来.
2 写txt本身肯定是慢的,你就单独使用复制-粘贴都慢,更不用说用程序写.
--------------------编程问答-------------------- 而且还存在一个问题,txt文件是否能放得下这么大的数据量 --------------------编程问答-------------------- 是不是平台工具的问题呀,我见过另外一个软件生成90多万条记录很快的,大概不到10秒钟。保存也很快。
用其他的平台是不是能解决这个问题,比如java或者c++ --------------------编程问答-------------------- 算法最重要,你明白吗。同样的算法,JAVA只会更慢。 --------------------编程问答-------------------- 非把这个问题搞清楚不可,如何能提高生成的速度和保存的速度。 --------------------编程问答-------------------- 要搞清楚的话,我现在来试一试吧!稍等片刻. --------------------编程问答-------------------- 好的。 --------------------编程问答-------------------- 需要我给你提供什么,我的 qq:37268998 EMAIL:HANGHWP@126.COM --------------------编程问答-------------------- 是啊,用分页,一页都显示出来有什么意义 --------------------编程问答-------------------- 楼上的伙计,不是我不用分页,后面还要对生成的这些数据进行处理,留下满足条件的数据删掉不满足条件的数据,用分页的话还需要都这些数据在分页读出来。 --------------------编程问答-------------------- 你用这样循环的方法肯定效率不高,不如直接对数据库操作,导出数据快. --------------------编程问答-------------------- 4楼的意见不错,不要用记录集,这样占内存的很,读一行写一行,是最佳办法,要想再快点就用多线程,分段读取,不过程序会很复杂的。 --------------------编程问答-------------------- 问题应该不在这里。写了个测试,存90万数据就几秒钟,68M, 楼主在查查其他的代码。
--------------------编程问答-------------------- 问题是这样会导致生成更慢。看来只有试下用多线程来保存了。 --------------------编程问答-------------------- 一些数据库本身就支持导出文本文件的查询
DataTable tb = new DataTable();
for (int i = 0; i < 8; i++)
{
tb.Columns.Add("a" + i.ToString());
}
for (int i = 0; i < 900000; i++)
{
DataRow dr = tb.NewRow();
for (int j = 0; j < 8; j++)
{
dr[j] = "aaaa7878";
}
tb.Rows.Add(dr);
}
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
DateTime dt1 = DateTime.Now;
StreamWriter sr;
if (File.Exists(saveFileDialog1.FileName)) //如果文件存在,则创建File.AppendText对象
{
sr = File.AppendText(saveFileDialog1.FileName);
}
else //如果文件不存在,则创建File.CreateText对象
{
sr = File.CreateText(saveFileDialog1.FileName);
}
foreach (DataRow dr in tb.Rows)
{
StringBuilder sb = new StringBuilder();
sb.Append(dr[0].ToString());
sb.Append("\t");
sb.Append(dr[1].ToString());
sb.Append("\t");
sb.Append(dr[2].ToString());
sb.Append("\t");
sb.Append(dr[3].ToString());
sb.Append("\t");
sb.Append(dr[4].ToString());
sb.Append("\t");
sb.Append(dr[5].ToString());
sb.Append("\t");
sb.Append(dr[6].ToString());
sb.Append("\t");
sb.Append(dr[7].ToString());
sb.Append("\t");
sr.WriteLine(sb.ToString());
}
sr.Close();
DateTime dt2 = DateTime.Now;
int kk = DateTime.Compare(dt2, dt1);
MessageBox.Show(kk.ToString());
Access的SQL语句,供参考:
SELECT * INTO [text;hdr=no;database=c:\temp].Table1.txt from Table1--------------------编程问答-------------------- 还是Mark!节点分好了。 --------------------编程问答-------------------- GOOD
http://topic.csdn.net/u/20080110/17/aae61ba2-7b1d-4954-9620-8754ff8ae585.html --------------------编程问答-------------------- 可惜要下班了;老天,昨晚本人的电脑电源烧了,没电脑用了.
但我有个问题不明白:
1 "后面还要对生成的这些数据进行处理,留下满足条件的数据删掉不满足条件的数据,用分页的话还需要都这些数据在分页读出来。"
处理数据的问题和显示界面有关吗?
2 为何要导出数据.
我想的法子是:
1 用户界面,只显示他需要的数据,可先读10000条记录,只需1-2秒吧,如果想快一点也可让读出数据少一点给用户看,想多看一点就加个分页;
2 用户在查询界面的同时,数据在导出,分段可设成10000条或任何级别的导;在上班啊,因没有时间,我做了一个1000000的循环虚拟写数据.
我的数据表记录是5000000条
所以问题的瓶颈可能在第三条的解决.
3 另一个问题就是写txt文件占用的资源了.得测,我想法是如果只写一个文件估计占用系统的虚拟内存过大,可否再分文件写,这样更优化一点,且无论以后有多大都可以扩展,只要你的硬盘空间允许.对应上第二条的分段.
我想:这样应该是占用系统的资源是最小的了.要想全部测试通过,得等本人电脑好了再说吧.
下班了,要回家喝奶了.88楼主.
--------------------编程问答-------------------- 4 测了一下,一下显示太多数据也是个瓶颈. --------------------编程问答-------------------- 谢谢lonelygames ,今天你一直在帮我看问题。明天在挂一天,不行就结贴。这样说吧,数据可以分页显示,但是保存的时候还是得把90w条数据全部保存起来呀,处理的时候也的把90w条数据用条件比较一遍,找出其中符合条件的,在交给下一个人来处理。其实就是一个筛选系统,刚开始可能有90w条记录,经过n次比较筛选以后剩下符合条件的也就没有多少条记录了。
现在就是刚开始数据量比较大的时候的速度的问题!!! --------------------编程问答-------------------- private void WriteTxt(DataTable tb)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamWriter sr;
if (File.Exists(saveFileDialog1.FileName)) //如果文件存在,则创建File.AppendText对象
{
sr = File.AppendText(saveFileDialog1.FileName);
}
else //如果文件不存在,则创建File.CreateText对象
{
sr = File.CreateText(saveFileDialog1.FileName);
}
foreach (DataRow dr in tb.Rows)
{
sr.WriteLine(dr[0].ToString() + "\t" + dr[1].ToString() + "\t" + dr[2].ToString() + "\t" + dr[3].ToString() + "\t" + dr[4].ToString() + "\t" + dr[5].ToString() + "\t" + dr[6].ToString() + "\t" + dr[7].ToString());
}
sr.Close();
}
}
试试在循环里加入sr.Flush();
foreach(DataRow dr in tb.Rows)
{
sr.WriteLine(dr[0].ToString()+ "\t" + dr[1].ToString()+"\t"+dr[2].ToString()+ "\t"+dr[3].ToString()+"\t"+dr[4].ToString()+ "\t" + dr[5].ToString()+\t"+dr[6].ToString() + "\t" + dr[7].ToString());
sr.Flush();
}
--------------------编程问答-------------------- 写一条 清空缓存一下!!! --------------------编程问答-------------------- 速度没有明显的改善· --------------------编程问答-------------------- 不知道生成XML的能快多少,但我做过一个XML的50W条数据,可能是数据很简单,
我只用13秒。楼主的.NET是2.0还是1.X的,如果是1.X的话就会很慢。
菜鸟问个问题:用异步的话是否会有阻塞的问题? --------------------编程问答-------------------- 楼主结题吧,都已很清楚了吧!
--------------------编程问答-------------------- 大家好,这里是新疆的.net QQ群体,欢迎大家加入(50794700) --------------------编程问答-------------------- 30m的txt文件,很难打开,没什么意义 --------------------编程问答-------------------- 那么应该考虑用数据库了。90W条数据放在文本里,文本不就是充当数据库的角色么?
说实话IO效率可没有数据库高,数据库有索引等优化手段。
赫赫,当然还得看工程成本了。 --------------------编程问答-------------------- 先mark,再做实验。
补充:.NET技术 , C#