ChronicleQueue新手疑问:如何从Tailer读取自定义MyData对象
用ChronicleQueue的Tailer.readDocument读取自定义MyData对象
嘿,我刚接触ChronicleQueue的时候也卡过这个点!既然你已经能成功写入MyData对象,说明序列化逻辑是没问题的,读取其实只要对应上Chronicle的反序列化机制就行,用readDocument的方式非常直接,我给你举几个直观的例子:
核心思路
tailer.readDocument()方法接收一个Consumer<Wire>参数,你可以在这个lambda里操作Wire对象,把队列里的二进制数据反序列化成你的MyData实例。Chronicle最常用的序列化方式是让自定义类实现Marshallable接口——既然你能写入,大概率已经这么做了,那读取就很简单。
方法1:直接用Marshallable.fromWire()(最简洁)
这种方式不需要提前创建MyData实例,Chronicle会帮你完成对象创建和反序列化:
// 获取tailer ExcerptTailer tailer = queue.createTailer(); // 读取单个MyData对象 MyData data = tailer.readDocument(wire -> Marshallable.fromWire(wire, MyData.class)); if (data != null) { // 处理你的数据,比如打印属性 System.out.println("字符串字段:" + data.getMyString()); System.out.println("数字字段:" + data.getMyNumber()); }
方法2:提前创建实例,用readMarshallable()
如果你想复用MyData实例(比如减少对象创建开销),可以先new一个对象,然后调用它的readMarshallable()方法:
MyData reusableData = new MyData(); ExcerptTailer tailer = queue.createTailer(); // 循环读取队列数据 while (true) { // readDocument返回boolean,表示是否成功读取到数据 boolean hasData = tailer.readDocument(wire -> reusableData.readMarshallable(wire)); if (!hasData) { // 队列暂时没有新数据,休眠100ms再重试 try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } continue; } // 处理复用的对象 System.out.println("读取到:" + reusableData); }
如果你用了自定义WireCodec
要是你没有让MyData实现Marshallable,而是用了自定义的WireCodec来写入,那读取的时候要对应使用这个Codec的read方法:
MyDataCodec codec = new MyDataCodec(); // 你自定义的Codec类 MyData data = new MyData(); ExcerptTailer tailer = queue.createTailer(); boolean success = tailer.readDocument(wire -> codec.read(wire, data)); if (success) { // 处理data }
关键提醒
- 当队列中没有可用数据时,
readDocument会立即返回null(方法1)或者false(方法2),所以在循环读取时最好加个短休眠,避免CPU空转 - 确保你的
MyData类的序列化逻辑(比如writeMarshallable方法)和读取逻辑完全对应,否则会出现反序列化错误
内容的提问来源于stack exchange,提问作者Sathish Kumar
相关产品推荐
相关产品推荐

