gpt4 book ai didi

java - 使用 Protocol Buffer 进行二进制日志记录

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:21:39 26 4
gpt4 key购买 nike

我们正在考虑将 Protocol Buffers 用于二进制日志记录,因为:

  • 这就是我们对对象进行编码的方式
  • 相对紧凑,读写速度快等。

也就是说,我们应该如何去做并不明显,因为 API 倾向于专注于创建整个对象,因此将 DataLogEntry 列表包装为 DataLogFile 中的重复字段将是您在消息传递中所做的术语,但我们真正想要的只是能够写入然后读取整个 DataLogEntry,将其附加到文件末尾。

我们这样做遇到的第一个问题是这样做(在测试中:

        FileInputStream fileIn = new FileInputStream(logFile);
CodedInputStream in = CodedInputStream.newInstance(fileIn);
while(!in.isAtEnd()) {
DataLogEntry entry = DataLogEntry.parseFrom(in);
// ... do stuff
}

仅导致从流中读取 1 个 DataLogEntry。没有 isAtEnd,它永远不会停止。

想法?

编辑:我已经切换到使用 entry.writeDelimitedTo 和 BidLogEntry.parseDelimitedFrom 并且这似乎有效...

最佳答案

根据我对 Protocol Buffer 的理解 does not support单个流中的多个消息。因此,您可能需要自己跟踪消息的边界。您可以通过在日志中的每条消息之前存储消息的大小来做到这一点。

public class DataLog {

public void write(final DataOutputStream out, final DataLogEntry entry) throws IOException {
out.writeInt(entry.getSerializedSize());
CodedOutputStream codedOut = CodedOutputStream.newInstance(out);
entry.writeTo(codedOut);
codedOut.flush();
}

public void read(final DataInputStream in) throws IOException {
byte[] buffer = new byte[4096];
while (true) {
try {
int size = in.readInt();
CodedInputStream codedIn;
if (size <= buffer.length) {
in.read(buffer, 0, size);
codedIn = CodedInputStream.newInstance(buffer, 0, size);
} else {
byte[] tmp = new byte[size];
in.read(tmp);
codedIn = CodedInputStream.newInstance(tmp);
}
DataLogEntry.parseFrom(codedIn);
// ... do stuff
}
catch (final EOFException e) {
break;
}
}
}
}

注意:我使用了 EOFException 来查找文件末尾,您可能希望使用定界符或手动跟踪读取的字节数。

关于java - 使用 Protocol Buffer 进行二进制日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2419241/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com