0

是否可以再次读取解压文件?

假设我使用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). 我知道,由于压缩算法的内部工作,可能无法仅在解压缩后的数据中寻找,并且数据不会存储在 libarchive 内部缓冲区中的有限字节数之外的任何地方。

这个想法是把它全部重置,然后读取std::streamoff off字节,这样我就可以创建反向搜索。前向搜索很容易,只需读取std::streamoff off字节。它确实效率低下,但让我们希望, seek 不会被太多使用。

整个结构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));

其中 container 包含大部分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);
    }

`

4

1 回答 1

0

Libarchive 文档,更准确地说,GitHub 上的 libarchive wiki 中的愿望清单说:

一些人要求能够有效地“重新阅读”特定的存档条目。这是一个棘手的话题。对于许多格式,由此带来的性能提升将非常有限。例如,通过一些性能工作,搜索 Zip 阅读器可以从头开始支持非常快速的重新阅读,因为它只涉及重新解析中央目录。会有实际收益的情况(例如,tar.gz)将很难处理。最可能的实现是某种形式的检查点,以便客户端可以明确地请求检查点对象,然后恢复到该检查点。如果您在格式处理程序本身中有一系列堆叠的读取过滤器和状态,则检查点对象可能会很复杂。

正如我看到的那样,在 libarchive 的帮助下在档案中寻找现在是不可能的,所以我的问题的一个解决方案是只在我怀疑我想重新阅读它时记住所有读取的数据,或者将它推回溪流。

于 2018-03-31T14:59:13.437 回答