读取大文本文件的速度问题

heytry 2008-01-18 02:36:45

CString sLine;
CString sAll;
while(tf.ReadString(sLine))
{
sAll += sLine;
}

用以上代码读取大一点的文本文件(1M以上)速度非常慢,why。

而我用记事本打开却没那么慢,记事本是怎么大文本的?
...全文
1185 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
open_sky 2008-01-22
  • 打赏
  • 举报
回复
1m至于吗
fox1999 2008-01-22
  • 打赏
  • 举报
回复
1M 就用內存映射呀?

殺雞雞用牛刀
llg84 2008-01-21
  • 打赏
  • 举报
回复

sAll += sLine;
改成
lstrcat(sAll, sLine);
=================================
没什么区别吧?同样要反复分配内存和复制
cnmmbd 2008-01-21
  • 打赏
  • 举报
回复
学习
OnTheWall 2008-01-21
  • 打赏
  • 举报
回复

sAll += sLine;
改成
lstrcat(sAll, sLine);
Torch009 2008-01-21
  • 打赏
  • 举报
回复
主要是sAll += sLine; 的开销很大
heytry 2008-01-21
  • 打赏
  • 举报
回复
嗯,是的,我最后就是用30楼所说的方法,没想到结贴了还有人回复,真是热心~~
marine8086 2008-01-21
  • 打赏
  • 举报
回复
其实关键在于不要一行一行地读,一次读个几K的,然后自己从缓存里分解出行.
Yangbin990 2008-01-20
  • 打赏
  • 举报
回复
up
heytry 2008-01-20
  • 打赏
  • 举报
回复
明白了各位,我就以二进制的方式读取的,很快的。
llg84 2008-01-20
  • 打赏
  • 举报
回复
16楼的,Read不是按二进制的方式读取的吗?那样能得到正确的字符串吗?是不是要进行转换?

而且文本文件的编码方式也不同,如果用Read读的话如何把读取后的数据转换成字符串?

说明下哈~~
========================================================================
读出来的二进制作为CString的构造函数参数传进去,cstring会自动转换的
wesen1111 2008-01-19
  • 打赏
  • 举报
回复
文件映射读的速度也不快,还没有ppfly2008 写的快
支持ppfly2008的方法
cnzdgs 2008-01-19
  • 打赏
  • 举报
回复
费了半天口舌,LZ还是没搞清楚问题在哪。
你按我说的,把文本文件的行数增加大原来的10倍,再执行你原本的程序,看看执行时间是原来的多少倍。
如果是读盘浪费了时间,增加行数后测试时间应该是原来的10倍左右;
如果是CString操作浪费时间,增加行数后测试时间应该是原来的100倍左右。
abcdrwl 2008-01-19
  • 打赏
  • 举报
回复
支持zhoujianhei,内存映射文件会快些,如下面

fh = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) {
return NULL;
}

hMapObject = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, name);

if (hMapObject != NULL) {
cdata = (char *) MapViewOfFile(
hMapObject,
FILE_MAP_READ,
0,
0,
0);

/* if (cdata == NULL) { */
CloseHandle(hMapObject);
/* } */
} else {
cdata = NULL;
}

CloseHandle (fh);
heytry 2008-01-19
  • 打赏
  • 举报
回复
不好意思各位,谢谢大家的解答,但分数比较少只能给前几位加分了.
heytry 2008-01-18
  • 打赏
  • 举报
回复
我用fread读取试了下速度确实快了点.
但有个问题是文本中应该有换行的,为何我读取了后放进CEdit中并无换行(CEdit有Multiline,Wantraturn属性)

而且在记事本中打开和AfxMessageBox还有用下面的DrawText都有换行的.
memDC.DrawText(tcsText, 1, &rc, DT_TOP|DT_LEFT|DT_EDITCONTROL);

而我要用
ReadString(sLine);
sLine.TrimR(_T(" \r\n"));
sLine += _T("\r\n");
这样在CEdit中显示才有换行,why?

是CEdit属性设置有问题吗?我是这样创建编辑框的
#define EDIT_STYLE1 WS_CHILD|WS_HSCROLL|WS_VSCROLL|ES_LEFT|ES_MULTILINE|ES_WANTRETURN|ES_NOHIDESEL|ES_AUTOHSCROLL|ES_AUTOVSCROLL

m_pEdit = new CEdit;
m_pEdit->Create(EDIT_STYLE1, CRect(0,0,0,0), this, IDC_SHOWPAD_EDIT);

m_pEdit->SetWindowText(从文件中读取的文本);
我怎么看都没问题啊,高手帮忙找找原因。
soft78 2008-01-18
  • 打赏
  • 举报
回复
内存映射
cnzdgs 2008-01-18
  • 打赏
  • 举报
回复
大家一通乱说,LZ都不知道该信谁的了。我再说详细点。
这段程序的时间是浪费在sAll += sLine;上,而不是读盘。
每次执行sAll += sLine,实际上需要先根据两个字符串的长度重新分配内存,然后再把两个字符串复制过去,再把原本的内存释放掉。当字符串较长时,分配、释放内存和复制字符串需要的时间都很长。
读文件的次数虽然也很多,但系统有磁盘缓冲区,所以不会每次都去读磁盘,所以这上面浪费的时间可以忽略。
哪位不信可以做程序试一下,假如把现有1MB的文件复制10份合成一个10MB的文件,执行时间绝对不止是原来的10倍,应该是100倍左右。
heytry 2008-01-18
  • 打赏
  • 举报
回复
16楼的,Read不是按二进制的方式读取的吗?那样能得到正确的字符串吗?是不是要进行转换?

而且文本文件的编码方式也不同,如果用Read读的话如何把读取后的数据转换成字符串?

说明下哈~~
buyong 2008-01-18
  • 打赏
  • 举报
回复
如果是VC,用CArchive不是很好么,可以参考CEditView::序列化的代码
加载更多回复(17)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧