1. 程式人生 > >磁碟搜尋之Java簡單實現

磁碟搜尋之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壓縮,最終將幾十兆的索引檔案壓縮到十兆之內。實際上,考慮到這些索引中以英文居多,我們可以採用更有效地壓縮演算法。

好了,就先寫這麼多吧。希望大家提出更好的辦法~~