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

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

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

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

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

#coding=utf-8

import os

import sqlite3

import 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+”盘索引建立完成”

#创建db

def 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

#插入记录到db

def 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语言实现,耗时应该更少。