好久没有用BCB了,妖哥来看看,请教个问题:如何提高在一个百兆的二进制文件里搜索指定的一个字符串,并写入到RichEdit里?

seaman117 2011-11-25 09:17:20
先准备用TMemoryStream载入文件,然后开缓冲区读出并查找,但是发现可能存在缓冲区截断KeyString的问题,现在的方法是
1. 先fopne(file , "rb")
2. ch = fgetc(file)
3. if(ch == Key[0]) fread Key后面剩余的字符,再strncmp(key , readkey)相等就输出到ricedit,不等再fseek后退读的个数
4. 循环3直到feof

现在测试一个50兆的文件基本上要十多秒,太慢了!
...全文
162 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
勉励前行 2011-11-30
  • 打赏
  • 举报
回复
用read直接讀入內存,因為有0存在,不要使用strcmp,用memcmp比strcmp快,可以考慮以下代碼(未測試):
char *FindString(char *buffBegin,char *buffEnd,char *str)
{
assert(buffBegin,buffEnd,str);
int L = strlen(str);
switch(L)
{
case 0 : break ;
case 1 :
for(char *p = buffBegin; p < buffEnd ; ++p)
if(*p == *str)
return p;
break ;
case 2 :
for(char *p = buffBegin; p < buffEnd ; ++p)
if(p[0] == str[0] && p[1] == str[1])
return p;
break ;
case 3 :
for(char *p = buffBegin; p < buffEnd ; ++p)
if(p[0] == str[0] && p[1] == str[1] && p[2] == str[2])
return p;
break ;
default: //取值為4, 是因為前4個字符相同,出現的幾率不多。
{ //可以測試下取值為2 3 4 以確認對於你的樣本而言,其最佳參數是多少。
char *cmpstr = str + 4 ;
L -= 4 ; //strlen == 4 時 L == 0 , 不影響 memcmp 的結果.
for(char *p = buffBegin; p < buffEnd ; ++p)
if(p[0] == str[0] && p[1] == str[1] && p[2] == str[2] && p[3] == str[3]
&& 0 == memcmp(cmpstr,p+4,L))
return p;//也可以測試下直接用 memcpy的結果是多少。
}
}
return NULL ;
}
My_Love 2011-11-29
  • 打赏
  • 举报
回复
TRichEdit有快速搜索字符串的源代码,一般人我不告诉他。
200M<1秒
seaman117 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lhylhy 的回复:]
引用 6 楼 seaman117 的回复:
引用 5 楼 ccrun 的回复:
直接将文件全部读入内存,在内存中查找,要比读一个字节比较一个字节快的多。

老妖,读入内存也是一个字节一个字节的查找啊,否则KeyString被截断会有数据没有被找

你为啥非要用strncmp?
[/Quote]
strncmp不快吗?

另测试了一下全部读入内存处理也要7-8秒时间,读入数据45M的文件。
cgl_lgs 2011-11-28
  • 打赏
  • 举报
回复
楼主的代码肯定有问题,我的应用在计算100MB文件的CRC都没那么慢。。。
hemiya 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 seaman117 的回复:]
另测试了一下全部读入内存处理也要7-8秒时间,读入数据45M的文件。
[/Quote]

机械硬盘虽然慢,但是读50M到内存不用花7~8秒.

系统内存多大,如果内存比较小,windows会用虚拟内存的,那就废时间了.
cgl_lgs 2011-11-28
  • 打赏
  • 举报
回复
当然不要用strncmp了,换成自己写的查找,一个字节一个字节的比较。
cgl_lgs 2011-11-25
  • 打赏
  • 举报
回复
你一次性读入内存就不用调用很多次的getc了。
ccrun.com 2011-11-25
  • 打赏
  • 举报
回复
直接将文件全部读入内存,在内存中查找,要比读一个字节比较一个字节快的多。
seaman117 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cgl_lgs 的回复:]
百兆而已,全部载入内存后检索。
[/Quote]
LoadMemory?那个有这个方法?
seaman117 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zzbinfo 的回复:]
用read会快一点
[/Quote]

是用的fread啊
cgl_lgs 2011-11-25
  • 打赏
  • 举报
回复
百兆而已,全部载入内存后检索。
zzbinfo 2011-11-25
  • 打赏
  • 举报
回复
用read会快一点
lhy 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 seaman117 的回复:]
引用 5 楼 ccrun 的回复:
直接将文件全部读入内存,在内存中查找,要比读一个字节比较一个字节快的多。

老妖,读入内存也是一个字节一个字节的查找啊,否则KeyString被截断会有数据没有被找
[/Quote]
你为啥非要用strncmp?
seaman117 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 ccrun 的回复:]
直接将文件全部读入内存,在内存中查找,要比读一个字节比较一个字节快的多。
[/Quote]
老妖,读入内存也是一个字节一个字节的查找啊,否则KeyString被截断会有数据没有被找

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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