有没有更好的方法可以从输入流中获取 Avro 记录列表?



我有一个用List<TestAvroModel>序列化的ByteArrayInputStream,它是SpecificRecord的实现。我找不到让 Avro 了解序列化列表的方法,所以我做了一个黑客的方式来循环ByteArrayInputStream.


//TestAvroModel is an implementation of SpecificRecord
List<TestAvroModel> models;
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
for(TestAvroModel model: models) {
DatumWriter<SpecificRecord> writer = new SpecificDatumWriter<>(model.getSchema());
Encoder encoder = new EncoderFactory().binaryEncoder(byteArrayStream, null);
writer.write(model, encoder);
encoder.flush();
}

//This was pre-serialized with a List of TestAvroModel
ByteArrayInputStream inputStream;
DatumReader<TestAvroModel> reader = new SpecificDatumReader<>(TestAvroModel.getClassSchema());
Decoder decoder = DecoderFactory().get().binaryDecoder(inputStream, null);
List<TestAvroModel> records = new ArrayList<>();
boolean eof = false;
while(!eof) {
try {
records.add(reader.read(null, decoder));
catch(EOFException ex) {
eof = true;
}
}

这种方式工作并一次读取一个序列化List<TestAvroModel>并将其添加到我的记录列表中。虽然循环DatumReader直到EOFException似乎不是最好的方法,但我还没有找到更好的方法。

我在 Avro图书馆中找不到任何处理包含多个 Avro 记录的InputStream的东西。尽管它必须在流中具有断点,以便 Avro 能够像我上面所做的那样读取单个记录。重申一下,有没有人知道比上面显示的更好的方法来循环DatumReader

Decoder似乎为此目的定义了isEnd(): Boolean

如果当前二进制解码器位于其源的末尾,则返回 true 数据,并且无法在不抛出 EOFException 的情况下进一步读取或 其他 IOException。

这应该有效:

...
while(!decoder.isEnd()) {
records.add(reader.read(null, decoder));
}

最新更新