Можно ли еще раз прочитать распакованный файл?
Давай представь что я использовал archive_read_next_header(a, &entry)
,
и я прочитал неизвестное количество байтов, используя archive_read_data(a, ptr_to_buffer, buffer_size)
, Прямо сейчас я хочу сбросить его и начать читать снова с самого начала. Я пытаюсь переопределить seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which)
, Я понимаю, что может быть невозможно просто искать внутри распакованных данных из-за внутренней работы алгоритмов сжатия, и данные не хранятся где-либо, кроме ограниченного количества байтов во внутреннем буфере архива.
Идея состоит в том, чтобы просто сбросить все и прочитать std::streamoff off
байты, таким образом, я мог создать обратный поиск. Поиск вперед будет легко, просто прочитайте std::streamoff off
байт. Это действительно неэффективно, но будем надеяться, что поиск не будет много использоваться.
Вся структура archive
был инициализирован таким образом:
archive_read_set_read_callback(a, read_callback);
archive_read_set_callback_data(a, container);
archive_read_set_seek_callback(a, seek_callback);
archive_read_set_skip_callback(a, skip_callback);
int r = (archive_read_open1(a));
где контейнер содержит больше всего std::istream
и обратные вызовы являются функциями, которые управляют этим потоком.
Шаблон того, чего я хотел бы достичь
`
std::streampos seek_beg(std::streamoff off) {
if(off >= 0) {
// read/skip 'off' bytes
} else {
// reset (a)
// read/skip 'off' bytes
}
// return position
}
`
также мой метод underflow () реализован таким образом:
`
int underflow() {
int r = archive_read_data(ar, ptr, BUFFER_SIZE);
if (r < 0) {
throw std::runtime_error("ERROR");
} else if (r == 0) {
return std::streambuf::traits_type::eof();
} else {
setg(ptr, ptr, ptr + r);
}
return std::streambuf::traits_type::to_int_type(*ptr);
}
`
Либархивная документация, точнее, Список желаний в вики-архиве на GitHub гласит:
Несколько человек попросили об умении эффективно «перечитывать» отдельные записи архива. Это сложная тема. Для многих
форматов, прирост производительности от этого будет очень скромным. За
Например, с небольшой производительностью работы, поиск читателя Zip может
поддержка очень быстрого перечитывания с самого начала, так как это включает в себя только
повторный анализ центрального каталога. Случаи, когда будут реальные
с доходами (например, tar.gz) будет очень трудно справиться.
наиболее вероятной реализацией будет некоторая форма контрольной точки, чтобы
клиенты могут явно запросить объект контрольной точки, а затем восстановить
вернуться к этой контрольной точке. Объект контрольной точки может быть сложным, если вы
иметь серию сложенных фильтров чтения плюс состояние в обработчике формата
сам.
Как я вижу, поиск в архивах с помощью libarchive в настоящее время невозможен, поэтому решение моей проблемы состояло в том, чтобы запомнить все прочитанные данные, только если у меня есть подозрения, что я захочу перечитать их, и в качестве альтернативы вернуть их обратно в поток.
Других решений пока нет …