Ищите в libarchive, как сбросить заголовок?

Можно ли еще раз прочитать распакованный файл?

Давай представь что я использовал 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);
    }

`

1 ответ

Решение

Документация по архивам, точнее, список пожеланий в вики-архивах на GitHub, гласит:

Несколько человек попросили об умении эффективно "перечитывать" отдельные записи архива. Это сложная тема. Для многих форматов выигрыш в производительности будет очень скромным. Например, при небольшом быстродействии ищущий Zip-ридер может с самого начала поддерживать очень быстрое перечитывание, так как он требует только повторного разбора центрального каталога. Случаи, когда будут реальные выгоды (например, tar.gz), будут очень сложными для обработки. Наиболее вероятной реализацией будет некоторая форма контрольной точки, чтобы клиенты могли явно запросить объект контрольной точки, а затем восстановить ее до этой контрольной точки. Объект контрольной точки может быть сложным, если в самом обработчике форматов есть несколько стековых фильтров чтения плюс состояние.

Как я вижу, поиск в архивах с помощью libarchive в настоящее время невозможен, поэтому решение моей проблемы состояло в том, чтобы запомнить все прочитанные данные, только если у меня есть подозрения, что я захочу перечитать их, и в качестве альтернативы вернуть их обратно в поток.

Другие вопросы по тегам