Пропуск байтов с помощью JsonParser Джексона - PullRequest
0 голосов
/ 03 мая 2018

В настоящее время у меня есть FileInputStream, который, как мне известно, содержит чередующиеся объекты (Metadata.class и BigInfo.class) в формате json, упорядоченные следующим образом:

[Метаданные1, BigInfo1, Метаданные2, BigInfo2, Метаданные3, BigInfo3, ...]

Я использую JsonParser Джексона для чтения таких как parser.readValueAs (Metadata.class) и parser.readValueAs (BigInfo.class).

Одна вещь, которой я хотел бы воспользоваться, состоит в том, что объекты метаданных содержат длину следующих сериализованных объектов 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', который использует произвольного доступа «искать» в позиции в файле.

Я пытался вызвать 'skip (bigInfoSize)' для базового inputStream анализатора. Однако это не работает, так как JsonParser читает и сохраняет информацию из inputStream во внутреннем буфере, поэтому позиция inputStream находится дальше, чем где находится анализатор.

Любые идеи о том, как подойти к этому, будут высоко оценены. Спасибо!

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Возможно, вы сможете сделать что-то подобное

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);
0 голосов
/ 07 мая 2018

Так что, посмотрев немного, я не думаю, что есть чистый способ сделать это с помощью jsonParser. Я закончил тем, что реализовал читатель для общего InputStream, который искал '{' и '}' (конечно, принимая во внимание вложенные объекты), и проанализировал базовый объект через ObjectMapper из полученного байтового массива.

...