【发布时间】:2018-03-07 15:14:47
【问题描述】:
我有一个包含 100,000+ 行的数据文件,每行只包含两个字段,用逗号分隔的键和值,并且所有键都是唯一。我想从这个文件中按键查询值。将其加载到地图是毫无问题的,因为这会消耗太多内存(代码将在嵌入式设备上运行)并且我不希望涉及数据库。到目前为止,我所做的是在我的 PC 中预处理文件,即对行进行排序,然后在预处理文件中使用如下所示的二进制搜索:
public long findKeyOffset(RandomAccessFile raf, String key)
throws IOException {
int blockSize = 8192;
long fileSize = raf.length();
long min = 0;
long max = (long) fileSize / blockSize;
long mid;
String line;
while (max - min > 1) {
mid = min + (long) ((max - min) / 2);
raf.seek(mid * blockSize);
if (mid > 0)
line = raf.readLine(); // probably a partial line
line = raf.readLine();
String[] parts = line.split(",");
if (key.compareTo(parts[0]) > 0) {
min = mid;
} else {
max = mid;
}
}
// find the right line
min = min * blockSize;
raf.seek(min);
if (min > 0)
line = raf.readLine();
while (true) {
min = raf.getFilePointer();
line = raf.readLine();
if (line == null)
break;
String[] parts = line.split(",");
if (line.compareTo(parts[0]) >= 0)
break;
}
raf.seek(min);
return min;
}
我认为有比这更好的解决方案。谁能给我一些启示?
【问题讨论】:
-
使用恒定时间排序算法怎么样?
-
“将其加载到地图是不可能的,因为这会消耗太多内存 [...] 到目前为止,我所做的是在我的 PC 中预处理文件,即对行,然后使用如下所示的二进制搜索“如果您的设备有足够的内存来对文件内容进行排序,那么它也有足够的内存来将其保存在地图中。
-
@TimothyTruckle 我在我的电脑上对其进行排序,然后将其复制到设备上。
-
将数据存储在适合嵌入式设备的数据库中,例如sqlite.org/whentouse.html 而不是在平面文件中并使用数据库 API 来检索数据?
-
@toongeorges 感谢您的提示,但我暂时不考虑 DB。也许我可以使用数据库的算法来索引文件以供以后查询。
标签: java algorithm file search random-access