2011-11-22 98 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并寻找密钥的位置。然后你可以阅读钥匙和价值。

相关问题