Используя протокол буферизует для двоичного входа

Мы думаем об использовании Буферов Протокола для двоичного входа потому что:

  • Это - как мы кодируем наши объекты так или иначе
  • Это относительно компактно, быстро для чтения / запись и т.д.

Тем не менее не очевидно, как мы должны пойти об этом, потому что 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, и это, кажется, работает...

7
задан Jamie McCrindle 10 March 2010 в 22:46
поделиться

1 ответ

Насколько я понимаю буферы протоколов, не поддерживает несколько сообщений в одном потоке. Так что вам, вероятно, придется самостоятельно отслеживать границы сообщений. вы можете сделать это, сохраняя размер сообщения перед каждым сообщением в журнале.

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

4
ответ дан 7 December 2019 в 05:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: