磁盘搜索之Java简单实现

引言:在使用电脑的时候,难免会遇到找不到本地文件的情况,而我们通常又记得文件名或者其中的几个关键字。当然一般系统都提供搜索方法,如windows的搜索,但其不全是基于文件名的,因而搜索效率显得低下。在基于文件名的文件搜索模式下,市面上有优秀的成品软件---著名的Everything,其原理我不多说了,简单一查就明白。下面我就谈谈我们用Java实现的一种基于文件名的文件搜索,希望大家提出更好的修改意见~~

 

1.  总的思路:先将文件系统的所有文件名(带路径)读入内存;再组织成一定数据结构的索引(方便检索用);同时添加监听器,响应文件系统的变化;退出时,将内存中对应的索引信息压缩存储到硬盘上;再次启动时,先从硬盘读入文件名信息、处理,然后在后台扫描磁盘,更新索引。

 

2.  文件名信息的获取:扫描全盘,可以采用递归或非递归的办法。如下非递归扫描:

 

Stack<String> folderStack = newStack<String>();//存放文件夹的临时栈

File[] roots = File.listRoots();//获取所有磁盘盘符

       for (int i = roots.length - 1; i >= 0; i--)

           folderStack.push(roots[i].toString());

 

       while (!folderStack.isEmpty())// 遍历

       {

           File[] fl = new File(folderStack.pop()).listFiles();

           if (fl == null)

              continue;

           for (int i = 0; i < fl.length; i++) {

              if (fl[i].isDirectory()) {

                  folderStack.push(fl[i].getAbsolutePath());

              } else {

                  index.add(fl[i].getAbsolutePath());

              }

           }

    }

该方法实现简单,但是效率低下。一种优化办法可以是借鉴Everything的方法,用C/C++写一个dll,在java代码里调用,后台执行。

 

3.  数据结构:改写的HashMap,其Key-Value类型是<String,ArrayList>。为了插入、删除的方便,我们改写了它此部分的实现:

public boolean put(String key, String value)

    {

       if(key == null)

           return false;

       int hash = hash(key.hashCode());

       int i = indexFor(hash, table.length);

       for(Entry e = table[i]; e!=null; e=e.next)

       {

           /*

            * 处理当前key已存在于hashMap的情况

            */

           if(e.hash == hash&&(key.equals(e.key)))

           {

              /*

               * 若value列表中存在当前value,插入失败

               */

              if(e.value.contains(value))

                  return false;

              e.value.add(value);

              size++;

              return true;

           }

       }

      

       modCount++;

       size++;

       addEntry(hash,key,value,i);

       return true;

}

删除实现在此就不列举了。考虑到一般电脑文件系统的文件数在10W以上的数量级,我们在确定HashMap的初始容量时需特别考虑,它直接影响构建Map的效率。

采用此HashMap带来的问题是:若是文件的全名,则可以根据文件名的散列值直接找到Value;否则,需要遍历整个Map;若要支持正则查询,需要处理查询条件,仍需遍历整个Map。

 

4.  监听器:由于文件系统的文件可以随时变化,所以在程序运行期间,我们需要检测其变化,并作出响应。这里,我们采用JNotify来实现。利用JNotify和Java多线程,我们完成了对多个磁盘的监听和处理。

 

5.  索引压缩存储:由于我们时间有限,直接采用了Java 包里提供的zip压缩,最终将几十兆的索引文件压缩到十兆之内。实际上,考虑到这些索引中以英文居多,我们可以采用更有效地压缩算法。

 

好了,就先写这么多吧。希望大家提出更好的办法~~
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值