2011-11-22 95 views
1

我需要爲大文本文件實現簡單的索引方案。文本文件包含鍵值對,我需要讀回特定的鍵值對,而不將整個文件加載到內存中。文本文件非常龐大,包含數百萬條記錄,而且鍵未被排序。根據用戶輸入需要讀取不同的鍵值對。所以我不想每次都讀完整個文件。請讓我知道java文件處理API中的確切類和方法,這將有助於以簡單高效的方式實現這一點。我想在不使用諸如lucene之類的外部庫的情況下執行此操作。在java中的文本文件上創建一個簡單的索引

+5

如果您想要的關鍵值對恰好是文件中的最後一個,那麼您將不得不在某個時間點閱讀整個內容。 – corsiKa

+0

如果你試圖找到一個不存在的密鑰,你必須閱讀整個文件。要索引文件,您可以閱讀一次,避免再次閱讀。文件有多大?您可能可以加載全部。 –

+0

對,他必須閱讀整個文件至少一次以便爲其編制索引。當您爲它編制索引時,您可以跟蹤每個鍵/值對的字節位置。然後,要檢索特定的鍵/值對,您將獲得其字節位置,然後跳到文件中的該位置以讀取該值。但是,如果值很小,所有這些功能可能都不值得,因爲索引本身會佔用大量內存。 – Michael

回答

5

正如評論指出的那樣,你將需要做的整個文件在最壞情況下的一半,平均線性搜索,和。幸運的是,你可以做一些技巧。

如果文件變化不大,則創建一個文件的副本,在該文件中對條目進行排序。理想情況下,副本中的記錄長度相同,以便您可以直接訪問排序文件中的第N個條目。

如果您沒有該磁盤空間,則創建一個索引文件,該文件將原始文件中的所有關鍵點都作爲關鍵字,並將原始文件的偏移量作爲值。再次使用固定長度記錄。或者更好的是,使這個索引文件成爲數據庫。或者將原始文件加載到數據庫中。無論哪種情況,磁盤存儲都很便宜。

編輯:要創建索引文件,使用RandomAccessFile打開主文件並順序讀取。在每個條目的開始處使用'getFilePointer()'方法來讀取文件中的位置,並將它加上索引文件中的密鑰。當查找某些內容從索引文件讀取文件指針並使用「seek(long)」方法跳轉到原始文件中的點時。

+0

其實我想問如何使用java文件處理api創建索引文件,以及哪些類/方法將有助於創建和讀取索引。 – vjain27

0

如何使用java掃描儀。

http://docs.oracle.com/javase/tutorial/essential/io/scanning.html

import java.io.*; 
import java.util.Scanner; 

public class ScanXan { 
    public static void main(String[] args) throws IOException { 
     Scanner s = null; 
     try { 
      s = new Scanner(new BufferedReader(new FileReader("xanadu.txt"))); 

      while (s.hasNext()) { 
       // **split the string and match it for your key here** 
       System.out.println(s.next()); 
      } 
     } finally { 
      if (s != null) { 
       s.close(); 
      } 
     } 
    } 
} 
2

我建議建立一個索引文件。掃描輸入文件並將每個鍵和它的偏移量寫入List,然後對列表進行排序並將其寫入索引文件。然後,只要你想查找一個鍵,就可以讀取索引文件並在列表中進行二分搜索。一旦找到需要的密鑰,打開數據文件RandomAccessFile並尋找密鑰的位置。然後你可以閱讀鑰匙和價值。

相關問題