private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox8.SelectedIndex >= 0)
            {
                if (comboBox8.SelectedIndex == 0)
                {
                    if (richTextBox1.Lines.Count() > 0)
                    {
                        string[] str;
                        for (int i = 0; i < richTextBox1.Lines.Count(); i++)
                        {
                            str = (richTextBox1.Lines[i].ToString()).Split(Convert.ToChar(" "));
                            switch (str[2])
                            {
                                case "-1":
                                    {
                                        listBox10.Items.Add(richTextBox1.Lines[i].ToString());
                                        break;
                                    }
                                case "未开通*":
                                    {
                                        listBox12.Items.Add(richTextBox1.Lines[i].ToString());
                                        break;
                                    }
                                default:
                                    {
                                        listBox11.Items.Add(richTextBox1.Lines[i].ToString());
                                        break;
                                    }
                            }
                            Application.DoEvents();
                        }
                    }
                    MessageBox.Show("处理完毕");                }一个软件是干什么用的?有人说得清楚吗?我认为:程序就是为了替代手工而存在。开发一个软件是给电脑盲的人使用,点击鼠标,按键盘,三两个简单的操作就能完成一些事情的处理。做了一个软件让别人使用,别搞得别人要懂得和你一样多才能使用该软件。
我遇到的烦恼就是:如上面一段代码是用来处理如下格式的字符串文本:a200005 123456 -1
b300001 123456 0
h600003 123456 193
c700008 123456 -1
abc2005 123456 未开通*
fghf008 123456 -1
dff9006 123456 684
abc2005 123456 未开通*这个文本非常大,假设有三千万条记录。我用上面的代码来处理,将其分为3类,一个“-1”类,一个是“未开通*”类,大于等于0的为第三类。在处理几千条的数据都还能忍受,但是我再处理8万左右条的数据时,我等了近4个小时还没处理完,就关机了,实在不能等。又测试处理3万5千条左右的数据,也花了3、4个小时处理完毕了,想保存的时候程序却假死掉了,但在任务管理器看见的是该程序正在运行,然而隔了一个晚上,第二天早上去看时还在运行,点击它却无任何反应。我的机器配置为AMD四核9550,内存2G单条DDR800,硬盘500G/32M缓存。系统为XP_sp3,VS2008开发工具。有人给我建议要使用到SQL数据库来处理,但从未接触过啊,怎么去做?谁能给我一点具体的建议?

解决方案 »

  1.   

    有人给我建议要使用到SQL数据库来处理
    --------------------确实,用企业级(如MS SQL Server、Oracle等)数据库来处理海量的数据效率会很高。
      

  2.   

    你这个文本格式的数据可以直接导入到数据库,去装个Sql Server试试吧。
      

  3.   

    程序就要傻瓜式使用方法。
    这种大量数据操作应该通过多线程和并发时处理方法
    也可使用数据库或XML实现数据保存,再处理
      

  4.   

    首先姑且不说放到数据库中的效率会有多高(是否真的高要看你怎么建表)。其次就这个问题来说,你这是个线性读取的时间复杂度是O(N),这个时间界无法改变(只是线性读取,不存在其他的算法要求)。最后,如果只是读取那么效率主要是在I/O上,你可以使用StreamReader来读取文件,由于你的数据量巨大,最好不要使用字符串函数。从你给出的采样数据来看,前两个段的长度是固定的,你可以读取流按字符偏移量读取,读到你需要的内容后装载到需要它的地方。你把3000W的数据显示在ListBox中肯定是不合适的。对于如此大数据量的装载最好放到数据库里面,分页读取(这里使用数据库是必要的)。
      

  5.   

    3000万条的数据量,处理起来不是问题,但是要效率的话估计不简单
    给楼主几个建议
    1、用数据库,要一些大中型的,象SQL、Oracle、MySQL等,就是ACCESS估计也不太能胜任
    2、可以考虑将文件分成多个小的文件再分别处理
    3、绝对不能把处理后的数据直接加到ListBox或者什么控件中去,应该直接写文件,还要用缓存;或者写到数据库的表中。
    4、多线程、异步什么的肯定要用
      

  6.   

    有道理。
    建议到网上搜一下关于提高数据库检索性能的文章看看。
    我现在的库里,第年会产生1亿6六万条数据。
    现在用的是sql2008
      

  7.   


    我举例的3000万数据,多数是10万至100万条记录的记事本文件,有数不清的那么多个,数据量可能达到1亿了。所以您的第二条建议不适用。我未接触过SQL,所以第一条也不适合我。第三条建议,之前的实验处理已经证实了ListBox或者什么控件没什么作用,速度慢死了。第四条建议,肯定是有用,不过我还是初学者,还未到那么高的地步。感谢您给了这么多建议。
      

  8.   


    看来是要学习一下SQL了,数据量太大,而且还在不断产生。
      

  9.   

    如此大的数据量就不要用控件了,直接写入文件性能要好得多.整个过程可以看做一个流水线:
    步骤a 将数据从文本按行读入内存缓冲区buf1.
    步骤b 从buf1中取出文本分析将结果送入buf2[x].
    步骤c 从buf2[x]取出一个结果写入指定的文件.其中a和c都涉及io操作,而且所涉及的每个文件的读/写都只能串性.所以
    IO部分可以看做性能最大的瓶颈,串行的话你有不少时间都会浪费在等待IO
    完成.b部分则完全可以充分发挥你的多核系统的性能,直接开4个线程来做.
    完成处理后将结果送往合适的buf2[x].c部分可以每个文件开一个线程循环
    从指定的buf2[x]取一个结果写入文件.整个流水线的主体部分在于缓存buf1
    和buf2[n]的设计.缓存说白了就是队列.重点是控制好大小和同步.最后b部分
    的算法再做下速度上的优化应该要比你原版串行的要快得多.----没有数据做测试,只能就这么把自己想的方法写出来了
      

  10.   

    如果数据量不是太大的话,这样还可以。3000万条记录,数据量太大了,如果每次改变选择项都要这么做,用户多点选几次,系统肯定吃不消。这个功能最好去掉,或者换个实现方式(不是技术实现,而是用户操作,比如让用户自己查询输入等),是否可以和需求人员谈谈?毕竟技术不是万能的,不可能用户要啥就有啥。有必要和用户再讨论一下需求问题。
    顺便网站推广一下,呵呵。http://www.subaru-gz.com斯巴鲁、雷诺
      

  11.   

    以下代码使用正则表达式匹配经测试:
    270万行资料的TXT文档(电脑配置为 E8200 2.66X2 内存2G 800 X2 =4G)
    如果使用单线程完成126秒左右
    (CPU 50%左右 内存占用 500Mb左右)开三个线程完成70秒左右(CPU 95%左右 内存占用 500Mb左右)
    因此,楼主如果每个小档案不超过几百万行,可以考虑使用以下代码
    如果某个档案数量高达1亿,那就算了,内存会不够的
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.IO;
    using System.Threading;namespace RegExpHugeWord
    {
        class Program
        {
            static void Main(string[] args)
            {
                string[] strContent = File.ReadAllLines(@"d:\1.txt");
                Console.WriteLine("共计" + strContent.Length.ToString() + "行\n");
                DateTime BeginTime = DateTime.Now;
                Thread thA, thB, thC;
                thA = new Thread(regTypeA);
                thB = new Thread(regTypeB);
                thC = new Thread(regTypeC);
                thA.Start();
                thB.Start();
                thC.Start();
                do
                {
                    Thread.Sleep(5000);
                } while (thA.IsAlive == true | thB.IsAlive == true | thC.IsAlive == true);
                if (thA.IsAlive)thA.Abort();
                if (thB.IsAlive) thB.Abort();
                if (thC.IsAlive) thC.Abort();
                DateTime EndTime = DateTime.Now;
                double dbMSec = EndTime.Subtract(BeginTime).TotalSeconds;
                Console.WriteLine("共计花费:" + dbMSec.ToString() + "秒\n");
                Console.ReadKey();
            }        //-1
            static void regTypeA()
            {
                String strContent = File.ReadAllText(@"d:\1.txt",Encoding.Default);
                Regex reg = new Regex(@"\S+\s\S+\s-1", RegexOptions.Singleline);
                StringBuilder sb = new StringBuilder();
                MatchCollection  results = reg.Matches(strContent);
                foreach (Match result in results)
                {
                    sb.Append(result.Value);
                    sb.Append(Environment.NewLine);
                }
                File.WriteAllText(@"d:\-1.txt", sb.ToString());
            }        //>=0
            static void regTypeB()
            {
                String strContent = File.ReadAllText(@"d:\1.txt", Encoding.Default);
                Regex reg = new Regex(@"\S+\s\S+\s\d+", RegexOptions.Singleline);
                StringBuilder sb = new StringBuilder();
                MatchCollection results = reg.Matches(strContent);
                foreach (Match result in results)
                {
                    sb.Append(result.Value);
                    sb.Append(Environment.NewLine);
                }
                File.WriteAllText(@"d:\0.txt", sb.ToString());
            }        //未开通*
            static void regTypeC()
            {
                String strContent = File.ReadAllText(@"d:\1.txt", Encoding.Default);
                Regex reg = new Regex(@"\S+\s\S+\s未开通\*", RegexOptions.Singleline);
                StringBuilder sb = new StringBuilder();
                MatchCollection results = reg.Matches(strContent);
                foreach (Match result in results)
                {
                    sb.Append(result.Value);
                    sb.Append(Environment.NewLine);
                }
                File.WriteAllText(@"d:\未开通.txt", sb.ToString());
            }
        }
    }
      

  12.   

    修正一下270万行资料的TXT文档(电脑配置为 E8200 2.66X2 内存2G 800 X2 =4G) 
    如果使用单线程完成126秒左右(CPU 50%左右 内存占用 500Mb左右)
    开三个线程完成70秒左右(CPU 95%左右 内存占用 1G左右
      

  13.   

    用正则吧~27L的就不错了,比起你那么多的case汗,case这样用会死人的……
      

  14.   

    为什么不用文件流,RichTextBox是包含文字格式的,如果你用它来检索某行数据,数据量大的时候会很慢的,你的筛选应该不会慢,慢在那个richTextBox1.Lines[i]的定位,而且你还在一个循环中多次定位。你可以尝试创建让richTextBox1内数据行减少为原来的1/100,看看时间是不是也只消耗原来的1/100,显然不会吧,所以是你那个richTextBox1的使用问题。
      

  15.   


    今天刚上来,发现您的代码,谢谢了。
    我的总数据记录超过一亿了,但每个文档的记录都是5万至50之间,没有100万以上记录的单个文档。
    相信您的c#水平已经达到了相当高的境界。能否留个QQ联系,或者加我513065668?不胜感激。
      

  16.   

    相信楼主很白,正则匹配效率往往很低,所以如果是规则的分隔符,就是用字符串的分割,速度可以更快。
    另外这段代码还不如使用thA.join()方法来得好呢,后面三个Abort()完全多余,压根不会被执行到。这样速度快?废话,直接操作文件,又是使用Foreach,无需二次定位,当然比你的快了,但却不是最好的方法,使用文件流的话,可以节约很多内存,内存紧张的情况下,优先考虑流读取,一行行读入。
      

  17.   

    有更好的高见?suihongxind onlyonly 密码错误*
    suihongxino onlyonly 0
    osuihongxin onlyonly -1
    qwuan7 wuguang 0
    wangzhaopeng521 1362385039 -1
    aj2388696 2388696aj 0
    jiangchenglu18 yelupan -203
    a66267247 a5821520 密码错误*
    chenyaoaiyi 454225105 0
    maoac123 6419755 -1
    siyubaby258 2594241ayy 699
    b65213832 82598188 -1
    qlyh963456 qlyh963456 0
    w52280320 kisskiss -1
    guyufengsj guyufeng12 密码错误*
    zlb13036767398 zxg1303676 766
    a86978430 707221324 -1
    yuxiang9899 li5117788 0
    能够用具体代码来处理以上数据格式?“考虑流读取,一行行读入”?这句话是否与我要表达的意思相反?我要做的是将上面的那个格式文本文件进行分类输出到3个记事本文件中。“-1”为一类,“密码错误*”为一类,其他的为一类。
      

  18.   

    "正则匹配效率往往很低" <-- 深表赞同,我只是提出了正则表达式的一种解,41楼貌似火气很大,呵呵
    正则表达式适合不规则的文字筛选再发布一个使用文件流的程式
    经测试 200W行 12秒,耗内存 100Mb左右楼主,看着采用吧
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;namespace HugeTextConvert
    {
        class Program
        {
            static void Main(string[] args)
            {
                DateTime Begin = DateTime.Now;
                DateTime End;
                FileStream fs = new FileStream(@"d:\A.txt", FileMode.Open);
                StreamReader sr = new StreamReader(fs);
                String strContent = "";
                List<String> TypeA = new List<String>();
                List<String> TypeB = new List<String>();
                List<String> TypeC = new List<String>();
                int i = 0;
                while (sr.Peek() >= 0)
                {
                    i++;
                    strContent = sr.ReadLine();
                    String[] sArray = strContent.Split(' ');
                    if (sArray.Length >= 2)
                    {
                        if (sArray[2].IndexOf("-1") == 0)
                        {
                            TypeA.Add(strContent);
                        }
                        else if (sArray[2].IndexOf("密码错误*") == 0)
                        {
                            TypeB.Add(strContent);
                        }
                        else
                        {
                            TypeC.Add(strContent);
                        }
                    }
                }
                File.WriteAllLines(@"d:\-1.txt", TypeA.ToArray());
                File.WriteAllLines(@"d:\密码错误.txt", TypeB.ToArray());
                File.WriteAllLines(@"d:\其他.txt", TypeC.ToArray());            if (fs != null) fs.Dispose();
                if (sr != null) sr.Dispose();
                
                Console.WriteLine(i.ToString() + Environment.NewLine);
                End = DateTime.Now;
                Console.WriteLine(End.Subtract(Begin).TotalSeconds + Environment.NewLine);
                Console.ReadKey();
            }
        }
    }
      

  19.   

    关于40楼这一句:"相信您的c#水平已经达到了相当高的境界。"
    我深表汗颜... ...
    其实我不懂C#的... ... 我只是用VB.NET写一些皮毛的东西...
    这个帽子扣大了... ...
      

  20.   


    老师,您谦虚了,我用你的代码来调试,弄半天也没弄出个头绪来,不是这报错,就是那报错,晕。
    很想问一下,您是在vs2008下调试通过的吗?我用的是vs2008.能否将您的能够调试通过的那个源程序发一个给我,让我详细参考并对比出我这里具体错在哪里。好吗?不胜感激。也感谢回复这贴的其他人,感谢你们为此提出各自的建议或意见。
      

  21.   

    “经测试 200W行 12秒,耗内存 100Mb左右”这个结果是我想都不敢想的,既然程序能达到这个速度,按照上面的应用来说,不需要数据库来处理了。哦,Lost_Painting老师,刚才忘记了留QQ了,现在附上:513065668  【HA 06】
      

  22.   

    呵呵,“我就不说怎么做了”怎么我觉得这句话好像是吊人胃口呢?明明我是很想知道该怎么做才能实现或者改进我那个垃圾代码,让它处理得更快,偏偏您就不说怎么做了?“总之数据库是适合初学者的最佳途径”这也是很撩人胃口的,我刚开始学c#的呀,一个简单的小程序都还没做得出来,又要放弃c#而去学SQL么?yuwenge,别见笑,您就当指点一下后辈们。
      

  23.   


    支持19楼的说法:  做软件项目是个系统工程,在某一个细节的改进措施是有极限的,
      暴露问题的环节,不一定是解决问题的最佳入手点。
      楼主没把问题的全貌呈现给大家,当了解全貌时可能感觉自己的改进措施很傻。  程序员要写傻瓜式软件,时刻注意别让自己变成傻瓜,要把复杂问题简化。比如:(1)数据采集得到的文本,分三类:“-1”、“未开通*”、“大于等于0”。能不能换成:-2、-1、>=0
      好处:数据量少了4*数万;
         数据类型变成了int范围处理,比“字符 + 数字”更简单。CPU也省点力(2)适时处理全部数据,只保存对今后有用的数据
      现在处理都感觉慢,把它存起来,别想今后让计算机再处理一次,还是这个速度,更不要想人工了。
      把好多垃圾数据存数据库,并且还考虑它将来无限增长。我是不是有点傻。(3) ... ...    软件的价值是给各行各业提供高效、便捷的信息服务,提高生产力。
      问题的核心是业务,软件只是工具。所以,一定要了解业务,再编代码。
      业务上的改进(系统设计),有时比代码优化有效的多。
      
      程序员抱怨,系统设计经常变更,是因为你不懂业务.你如果懂业务,你可以说服他,按照你的思路走。
      

  24.   

    程式倒是不用发上去了
    你新建一个控制台程式,然后把我的代码贴进去就可以运行第一个方法,确保 D:\下有1.txt
    第二个方法,确保 D:\下有A.txt如果中途有错自己调试下即可,都不是什么复杂的东西的
      

  25.   

    结贴了。Lost_Painting的代码我已经调试通过,并得到最高的效率。
    故此贴的所有回复的人,分配给Lost_Painting  90分,其他酌情给一些,这没有什么好说的,因为你们只说不做,没有代码供我调试。
    也劝告除Lost_Painting之外的一些人,在公司打工只说不做很快会被炒鱿鱼的,除非你是老板。做永远重要于说。