讨论:FindNextFile的实现 及 “搜索缓存”

guogangj 2008-04-02 11:05:25
我们都有这么一个体验:用windows的资源管理器在“我的电脑”里查找一个文件,第一次可能会耗费相当长的时间,但如果刚查找玩A文件,我们马上接着在同样的范围内查找B文件的话,这时候会发现,速度快了很多很多,可能前面用了一分钟,后面只用了几秒钟,甚至更少。两者的区别,我们明显能感觉到,第一次是真实的查找,你会发觉硬盘“ga zi ga zi”作响,(如果你的硬盘不够好的话^_^),第二次明显不是真实的查找,硬盘貌似没动作。

自己写文件遍历,你会发现也是这样的。(使用FindFirstFile/FindNextFile函数)

如果你在使用自己的遍历程序之前,对目标范围进行一次用资源管理器的search操作,你会惊奇发现,你的遍历程序也快得惊人。

这说明内部有个缓存,但这个缓存并非永久保留,过了10来分钟(大约),你再重新search,速度又变为慢速了,这时候磁盘也恢复“ga zi ga zi”的响声。

另外:不知道你是否查看过IE的缓存,这个缓存在我的电脑上是这个目录:
C:\Documents and Settings\guogangj\Local Settings\Temporary Internet Files\Content.IE5
之下还有一些子目录,第一次打开这些子目录需要耗费大量的时间,打开完毕之后你会发现其实文件没有预料中的多,之后再访问这些目录就很快了,这明显也使用了缓存,只是我不太明白为什么第一次会这么慢。当然这个问题是次要的了。

我不得不佩服微软的细心,所以开这个帖子来讨论一下FindNextFile的内部实现,如果我们以后需要类似的功能,如何来实现这个“缓存”。
...全文
106 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
cnzdgs 2008-04-02
系统磁盘缓冲就是把你访问过的磁盘扇区的数据先放到内存里面。当要读磁盘时,首先检查磁盘缓冲中是否存在要读取的扇区,如果存在则直接从缓冲中读取数据,如果不存在则另外分配缓冲区把磁盘中的数据读进来再从缓冲区中读取;当要写磁盘时,先把数据写入到缓冲区,然后在适当的时机写入磁盘。系统的磁盘缓冲是系统自动调度的,需要时可能会开很多个缓冲区,几百MB很常见,当物理内存不足时会自动释放掉一些不常用的缓冲区,当缓冲区长时间不使用时也会释放掉。FindFile对于磁盘的操作就是把文件系统的索引(目录)数据读出来,然后从中查找文件,当执行了一次全盘FindFile后,所有的索引数据就都已经读到磁盘缓冲区中了,只要这些缓冲区不释放,再次执行搜索就不需要再读磁盘,所以速度很快。如果此后执行了需要大量物理内存的操作,例如大量复制数据,导致文件系统索引所占用的磁盘缓冲被释放掉,再执行FindFile就会变慢了。
回复
zhoujianhei 2008-04-02
1. nt 的内存分页机制导致。
系统分配虚拟内存用于保存文件目录扇,查找结束后释放并标记为脏页,在系统(System Idle 线程)回收之前进行第二次查找,将重新提交该页。
2. 磁盘自带的内部缓存。
进行磁盘文件操作之后最近的访问的扇区将被缓存。
回复
guogangj 2008-04-02
估计如cnzdgs 所言,我进一步学习中,因为只要搜索过那个区域,无论紧接着搜索什么什么内容,速度都飞快,这个缓冲如何实现呢?

如果中间增加删除了一些文件,缓冲如何来维护呢?这个…… who can answer me?
回复
draculacsdn 2008-04-02
所有文件遍历建立一个索引和相关文字建议多个索引所用的时间应该不会有很大差距,所以类似自学习的搜索条件应该会被采用。例如如果第一次搜索的关键字是a,第二次搜索的关键字是“啊”,那么速度就不会有变化;如果第二次搜索的关键字是b就会快很多。所以推测应该有选择的建立多个索引。
回复
cnzdgs 2008-04-02
这是系统磁盘缓冲的效果,与FindFile内部无任何关系。
回复
txk1452 2008-04-02
磁盘访问需要时间的,拿一个FAT系统来说,如果访问一个目录或文件,要通用FAT表和目录项来定们文件位置,当然,FAT表可能是一次性装入内存,但目录项就不可能了!所以,无论是查找还是文件读写都要进行文件在磁盘上的定位!至于以后为什么会快,就以striking所说的,系统可能创建了index!至于是怎么实现的可能要问MS大哥了!
回复
guogangj 2008-04-02
如果第一次查找文件A,查找完毕后在查找区域创建多个文件A,你会发现新创建的文件也是完全可以查找到的,看来不完全是看index,这玩意儿技术含量还蛮高的。
回复
striking 2008-04-02
我忽然想到的

windows在第一次搜索 为关键字创建index 供下次使用 所以第一次慢

findnextfile 其实通过句柄在缓存找index

其实是不是可以这样想 findnextfile只是通过句柄跟index之间的映射返回给用户

而index是windows在后台通过某种服务创建 存在硬盘上的真实的东西
回复
passionhip 2008-04-02
mark
回复
striking 2008-04-02
回答很精彩啊
回复
guogangj 2008-04-02
嗯……我想起来我以前有个程序频繁读写磁盘的,我还担心这样会伤硬盘,看来借助了buff的话,我的担心是没什么必要的了。
回复
jingzhongrong 2008-04-02
楼上说的好啊
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2008-04-02 11:05
社区公告

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