BufferedInputStream
не ищется. Чтобы искать в обратном направлении, вам нужно будет уничтожить bufferedStream
, а затем искать базовый дескриптор файла, например, с помощью lseek()
, а затем создать новый буферный поток.
Обратите внимание, что читается текущая позиция (по порядку переходить к lseek()
позже к go back) также сложно, если буферизованный поток присутствует, так как буферизованный поток будет считывать данные после позиции, чтобы заполнить буфер. Вы можете вычислить его, вычтя из размера буфера, например:
// Determine current file position, so that we can seek to it later.
off_t messageStartPos = lseek(fd, 0, SEEK_CUR) -
bufferedStream.tryGetReadBuffer().size();
// Read a message
{
capnp::PackedMessageReader message(bufferedStream);
// ... do stuff with `message` ...
// Note that `message` is destroyed at this }. It's important that this
// happens before querying the buffered stream again, because
// PackedMesasgeReader updates the buffer position in its destructor.
}
// Determine the end position of the message (if you need it?).
off_t messageEndPos = lseek(fd, 0, SEEK_CUR) -
bufferedStream.tryGetReadBuffer().size();
bufferedStream.read((void*)framePtr.begin(), framePtr.size());
FWIW, эффект этой строки - «перейти от текущего буфера к следующему». Вы не хотите делать это при использовании PackedMessageReader
, так как он уже продвинет сам поток. Фактически, поскольку PackedMessageReader
, возможно, уже продвинулся дальше текущего буфера, framePtr
теперь может быть недопустимым, и эта строка может вызвать ошибку.
Альтернатива: Прочитав весь файл один раз, станьте владельцем данных и сохраните их в векторе. Например, как описано здесь (https://groups.google.com/forum/#! Topic / capnproto / Kg_Su1NnPOY ). Лучшее решение с самого начала?
Если файл удобно помещается в ОЗУ, то чтение его заранее, как правило, хорошо, и, вероятно, будет хорошей идеей, если вы будете много и много искать.
Другой вариант - mmap()
. При этом создается впечатление, что файл находится в ОЗУ, но операционная система фактически читает содержимое по требованию при обращении к ним.
Однако я не думаю, что это действительно сильно упростит код , Теперь вы будете иметь дело с ArrayInputStream
(подкласс BufferedInputStream
). Чтобы «искать», вы должны создать новый ArrayInputStream
, основанный на срезе буфера, начиная с той точки, с которой вы хотите начать.