0

除了遍历整个文件,还有没有快速读取最后一条记录的方法?我找到的最接近的解决方案是:有一个seek(long filePosition)函数DataFileReader可以直接到达一个有效的文件位置,从那时起,我需要遍历到最后。在这种情况下,在每次写入期间,我都需要更新此文件位置,这会导致两次写入(一次写入 Avro 文件,一次写入更新文件位置)。双重写入会带来很多一致性问题。

请让我知道是否存在任何自给自足的溶液。每条记录的长度都是可变的。

提前致谢。

4

1 回答 1

0

我不确切知道您的用例,因此此解决方案可能不适合您的需求(特别是因为您需要写入文件并再次读取它(?))。在我的例子中,我需要随机访问 Java 中的 .avro 文件(按键)。我所做的是在我的应用程序启动时读取整个文件并将其加载到 HashMap 中的内存中。这样,按键访问是O(1)。在您的情况下,由于您需要按索引(最后一个)访问,您可以使用 List 而不是 HashMap,并且您的读取将是 O(1)。

这是将文件加载到内存中:

public Map<String, Height> loadHeights(String... files) throws IOException {
    Map<String, Height> map = new HashMap<>();
    for(String file: files) {
        GenericDatumReader datum = new GenericDatumReader();
        DataFileReader reader = new DataFileReader(new File(file), datum);

        GenericData.Record record = new GenericData.Record(reader.getSchema());
        while (reader.hasNext()) {
            reader.next(record);
            map.put(record.get("NETW_ID").toString(), new Height(Integer.valueOf(record.get("CHAINAGE").toString()), Integer.valueOf(record.get("HEIGHT").toString()), Integer.valueOf(record.get("VERTICAL_ERROR").toString())));
        }
        reader.close();
    }
    return map;
}

并以 O(1) 复杂度从中读取:

private Height getHeightBySegmentId(String segmentId) {
    Height height = altitudes.get(segmentId);
    return height == null ? new Height() : height;
}

在您使用列表的情况下,它将类似于:

public List<Height> loadHeights(String... files) throws IOException {
    List<Height> list = new HashMap<>();
    for(String file: files) {
        GenericDatumReader datum = new GenericDatumReader();
        DataFileReader reader = new DataFileReader(new File(file), datum);

        GenericData.Record record = new GenericData.Record(reader.getSchema());
        while (reader.hasNext()) {
            reader.next(record);
            list.add(new Height(Integer.valueOf(record.get("CHAINAGE").toString()), Integer.valueOf(record.get("HEIGHT").toString()), Integer.valueOf(record.get("VERTICAL_ERROR").toString())));
        }
        reader.close();
    }
    return list;
}

并以 O(1) 复杂度从中读取:

private Height getHeightByIndex(int index) {
    Height height = altitudes.get(index);
    return height == null ? new Height() : height;
}
于 2020-06-24T07:01:57.457 回答