Мы думаем об использовании Буферов Протокола для двоичного входа потому что:
Тем не менее не очевидно, как мы должны пойти об этом, потому что 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, и это, кажется, работает...
Насколько я понимаю буферы протоколов, не поддерживает несколько сообщений в одном потоке. Так что вам, вероятно, придется самостоятельно отслеживать границы сообщений. вы можете сделать это, сохраняя размер сообщения перед каждым сообщением в журнале.
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;
}
}
}
}
NB: Я использовал EOFException, чтобы найти конец файла, вы можете использовать разделитель или отслеживать количество байтов, прочитанных вручную.