首页 > 解决方案 > 使用 Jackson JsonParser 跳过字节

问题描述

我目前有一个 FileInputStream,我知道它包含 json 格式的交错对象(Metadata.class 和 BigInfo.class),排序如下:

[元数据1,大信息1,元数据2,大信息2,元数据3,大信息3,...]

我正在使用 Jackson 的 JsonParser 来读取这些,例如 parser.readValueAs(Metadata.class) 和 parser.readValueAs(BigInfo.class)。

我想利用的一件事是 Metadata 对象包含以下序列化 BigInfo 对象的长度,以及我是否需要阅读它。所以我希望能够跳过对应于 BigInfo 对象的适当字节数,如果我不需要阅读它:

Metadata metadata = parser.readValueAs(Metadata.class);
// Whether I need to read the BigInfo object that comes after
boolean mustRead = metadata.isMustReadBigInfo();
if (!mustRead) {
    // Size of the bigInfo object that comes after
    int bigInfoSize = metadata.getBigInfoSize();
    parser.skip(bigInfoSize); // This 'skip' method is needed
}

我可以通过使用 parser.skipChildren() 来实现“跳过”,但这会顺序读取(并丢弃)inputStream 的所有字节,并且会比底层 FileInputStream 的“skip”方法慢得多,后者使用随机访问“查找”到文件中的某个位置。

我尝试在解析器的底层 inputStream 上调用“skip(bigInfoSize)”。但是,这不起作用,因为 JsonParser 从 inputStream 读取信息并将其存储在内部缓冲区中,因此 inputStream 的位置比解析器所在的位置更远。

任何有关如何解决此问题的想法将不胜感激。谢谢!

标签: javajacksonjackson-databind

解决方案


你也许可以做这样的事情

RandomAccessFile file = new RandomAccessFile(filename, "r");
InputStream inputStream = Channels.newInputStream(file.getChannel());
file.seek(byteLocationToSkipTo); //This allows you to set file pointer to this location
JsonParser parser = new JsonFactory().createParser(inputStream);
Map<String, Object> map = parser.readValueAs(Metadata.class);

推荐阅读