Everything原理及全盘搜索研究

来源:互联网 发布:淘宝代码 编辑:程序博客网 时间:2024/05/16 13:45

Everything是个十分方便的本地文件搜索软件,谁用谁知道...一般每次启动后,它会有个初始化时间,初始化完成后,每次搜索,结果秒出。

有一篇文章是讲Everything实现原理的,详情猛戳此处

大体意思是,ntfs磁盘分区会有一个觉usn的日志系统,从这个日志系统中可以拿到类似全盘索引之类的数据,然后搜索时从这个数据格式出发,效率会比较高。但有个致命点是fat32格式的分区并没有这个usn系统,而且usn系统会返回所有相关的文件信息,不灵活。我的分区全是ntfs的,没有测试everything是否支持fat32,我想应该也是支持的,不过关对于fat32,Everything应该是使用了其他的方案。

起始基于初始化+N次搜索的思想,完全可以不实用usn这个东西。在第一次启动的时候,做一次全盘扫描,建立全盘文件索引到数据库。之后开一个线程监控磁盘,当发生文件的增加、修改、删除时,同步到数据库中。在每次搜索时,从数据库中查找,也是可以的。这样就不必要求磁盘必须是usn的。另外,可以灵活的选择需要哪些文件信息。

下面先使用python实现了这个思想,数据库使用的sqlite3,暂时没有开监控线程。数据库暂时没有优化。


#coding=utf-8import osimport sqlite3import time#全局变量,记录文件数目global  file_number#遍历disk磁盘def all_files(disk):    global  file_number    print "建立"+disk+"盘索引..."    dir_path = disk+":"    for root ,subdirs, files in os.walk(dir_path):          for file in files:              filefullpath = os.path.join(root,file)              print 'file_path: '+filefullpath+'   file_name: '+file+"\n"            insert_to_db(filefullpath,file)            file_number += 1    print disk+"盘索引建立完成"#创建dbdef create_db():    sqlite_con = sqlite3.connect('d:/mydatabase.db')    sqlite_cur = sqlite_con.cursor()    sqlite_cur.execute('CREATE TABLE FOO (o_id INTEGER PRIMARY KEY, file_path VARCHAR(260), file_name VARCHAR(260))')    sqlite_con.commit#插入记录到dbdef insert_to_db(file_path,file_name):    con = sqlite3.connect('d:/mydatabase.db')    cur = con.cursor()    cur.execute('INSERT INTO foo (o_id, file_path, file_name) VALUES(NULL, ?, ?)',[file_path.decode('gbk'),file_name.decode('gbk')])    con.commit()#初始化数据def InitDB():    print "开始建立文件索引,请等待..."    global  file_number    file_number = 0    time_start = time.clock()    create_db()    all_files("c")    all_files("d")    all_files("e")    all_files("f")    time_end = time.clock()    print "文件索引建立完毕!"    print "用时: "+str(time_end)    print "文件数: "+str(file_number)#查找def find_file(file_name):    find_con = sqlite3.connect('d:/mydatabase.db')    find_cur = find_con.cursor()    find_cur.execute('SELECT * FROM FOO WHERE file_name = ?',[file_name.decode('gbk')])    find_con.commit    find_con.close    print find_cur.fetchall()if __name__ == "__main__":    if(os.path.exists('d:\mydatabase.db') == False):        InitDB()    while(1):        find_file_name = raw_input("输入要查找的文件名:")        if(find_file_name == "#exit"):            break        find_file(find_file_name)                


这个程序在执行初始化扫面全盘时,还是比较耗时的,主要瓶颈在sqlite的IO上,这这个Blog的时候,程序已经跑了至少5分钟了,目测扫了40%的数据...估计全盘骚下来得10多分钟。。。。。
后面有时间了优化下看看初始化的耗时情况,另外,如果用C语言实现,耗时应该更少。

再有时间了再研究下基于usn的方案怎么实现。

原创粉丝点击