我需要为大文本文件实现一个简单的索引方案。文本文件包含键值对,我需要回读一个特定的键值对而不在内存中加载完整的文件。文本文件很大,包含数百万个条目,并且密钥未排序。根据用户输入,需要读取不同的键值对。所以我不想每次都阅读完整的文件。请让我知道java文件处理api中的确切类和方法,这将有助于以简单有效的方式实现它。我想在不使用外部库(如lucene)的情况下执行此操作。
答案 0 :(得分:5)
正如评论所指出的,在最坏的情况下,你需要对整个文件进行线性搜索,平均需要一半。但幸运的是,你可以做一些技巧。
如果文件没有太大变化,则创建一个文件的副本,在该文件中对条目进行排序。理想情况下,在副本中创建相同长度的记录,以便您可以直接进入已排序文件中的第N个条目。
如果没有磁盘空间,则创建一个索引文件,该文件将原始文件中的所有键作为键,并将原始文件中的键作为值。再次使用固定长度记录。或者更好,将此索引文件设为数据库。或者将原始文件加载到数据库中。在任何一种情况下,磁盘存储都非常便宜。
编辑:要创建索引文件,请使用RandomAccessFile打开主文件并按顺序读取。在每个条目的开头使用'getFilePointer()'方法来读取文件中的位置,并将该密钥存储在索引文件中。查找某些内容时,请从索引文件中读取文件指针,并使用“seek(long)”方法跳转到原始文件中的点。
答案 1 :(得分:2)
我建议建立一个索引文件。扫描输入文件并将每个键及其偏移量写入List
,然后对列表进行排序并将其写入索引文件。然后,只要您想查找某个键,就可以读入索引文件并在列表中进行二进制搜索。找到所需的密钥后,将数据文件打开为RandomAccessFile
并查找密钥的位置。然后你可以读取键和值。
答案 2 :(得分:-1)
如何使用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();
}
}
}
}