本帖最后由 LENOVO_ 于 2010-02-19 22:39:30 编辑

解决方案 »

  1.   

    你这种读文件的方式,得确很慢,每次都是读取16个字节,这样I/O太繁忙了,最好是一次多读取一些在内存缓存,然后再处理,一般读取时就以Windows页面大小4K大小读取最佳。另外你还得考虑用滑动窗口的方式分段读取,文件小的时候没事,一旦文件大了,你的这个程序打开一个文件超级慢。象你这样上1M的文件处理起来都会很慢。至于自动对应的问题倒没事,因为因可以知道两个框中的具体字符串位置,然后用SetSel来选中就行了。
      

  2.   

    我认为效率低并不是一次读取数据太少造成的,因为这些常用的文件读写函数本身已经提供了4k的缓冲区。
    hexdata+=pBuf;这样的语句用起来很简单吧,问题就在这里。每附加一次数据,CString都得分配一个更大块的内存,把旧的和新的数据copy进去,然后把旧的内存区释放的。这些都是费时的操作。用Preallocate(int n)预先分配一大块内存,速度就上去了。
      

  3.   

    回 1 楼的,我试了一下,读 1.10MB的WMA音乐文件,刚开始会卡住一会,象UltraEdit这种软件可以一下子打开,不过往下刷的时候会出现闪烁,过一会就好了。主要是一次读多了,不好插入"\r\n",你说的滑动窗口和分段读取我不知道怎么写代码,没写过。回 2 楼,确实慢。回 3 楼,确实你说的对,每次 += 都要复制一遍旧串。Preallocate(int n) 没用过,网上查了一下,也说得乱七八糟的。谢谢几位的回复,我还需要等待,等待更具体一点的指点。
      

  4.   

    开个大的buf去读吧,效率的事情由系统去做。
      

  5.   

    preallocate是CString的一个成员函数,用于预先保存一定的内存,这样在连接字符串的时候在内存未用完之前,只要把新串加到后面就行了。拿你的代码来说吧:
            int readnumber=0;
            FILE* fpopen=NULL;
            CString hexdata;
            CString charactor;
    加到这里:hexdata.preallocate(40960);
             charactor.preallocate(40960);
    预分配的内存越大,速度会越快。
      

  6.   

    回 5 楼,谢谢。回 “宏景工作室”,采纳了你的意见后,发现快了好几倍。我首先获取文件的大小,然后计算出要分配多少内存空间。
    CFileStatus filestatus;
    unsigned long int filesize=0;
    if( CFile::GetStatus(sourcefile.GetPathName(),filestatus) )  //获取文件大小
    {
    filesize=filestatus.m_size;
    } hexdata.Preallocate(filesize*3 + (filesize/16)*2 + 16);
    charactor.Preallocate(filesize + (filesize/16)*2 + 16);用 GetTickCount()计算出从打开 1.10MB的文件到显示出数据到Rich Edit 是2328毫秒。原来没有先 Preallocate 的用了6331毫秒。确实被你说中了,谢谢指点。那个每次读多少字节就算了,暂且不管他了。现在来研究一下,怎么实现鼠标选择后,框住另外一边的效果。先谢谢你了,我再研究一下。
      

  7.   

    这个文本框的字符是一一对应的,这就好办了。主要是处理en_selchange事件,每当光标位置或选择的内容有变化时,就会出现这个事件。发生这个事件时,可以取得当前光标的位置或选择的起终位置。然后把字符框设置一下就行了.
      

  8.   

    其实你可以用createfile()来打开文件,它的最后一个参数是可以优化读取速度的
      

  9.   

    回 8 楼,我尝试了一下你说的 EN_CHANGE 事件,(你说的那个EN_SELCHANGE我没找到消息映射宏,汗!找了半天)。也用到了SetEventMask(GetEventMask() | ENM_CHANGE | ENM_SELCHANGE),都没用。无奈!只好响应ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_PAINT()
    void CMyDialog::OnMouseMove(UINT nFlags, CPoint point)
    {
    if(nFlags == MK_LBUTTON)
    {
    richedit1->GetSel(nStartChar,nEndChar);
    richedit2->SetSel(nStartChar/3,nEndChar/3);
    flag=0;
    Invalidate();

    } CDialog::OnMouseMove(nFlags,point);
    }void CMyDialog::OnPaint()
    {

    CHARFORMAT2 cfm;
    cfm.cbSize=sizeof(cfm);
    richedit2->GetSelectionCharFormat(cfm);
    cfm.dwEffects=0;
    if(flag == 0)
    {
    cfm.crTextColor=RGB(255,255,255);   //蓝底白字
    cfm.crBackColor=RGB(10,36,106);
    }
    else if(flag == 1)
    {
    cfm.crTextColor=RGB(0,0,0);        //白底黑字
    cfm.crBackColor=RGB(255,255,255);
    }
    cfm.dwMask=CFM_BACKCOLOR | CFM_COLOR;
    richedit2->SetSelectionCharFormat(cfm); CDialog::OnPaint();

    }void CMyDialog::OnLButtonDown(UINT nFlags, CPoint point)
    { richedit2->SetSel(nStartChar/3,nEndChar/3);
    flag=1;
    Invalidate();
    }
    哎,每次都是必须把光标移动到 Rich Edit控件外才能重绘,还要按着左键。
    好像光标在空间范围里面就不响应消息。
    糟糕透了!都搞了   6 个小时了。
    真是麻烦。
    继续做一下,再做不出来就不搞了。
      

  10.   

    vs2008带的MFC中有selchanage不知道,不知道你用的是什么?
      

  11.   


    preallocate,我也学习ing谢谢!