寻求libarchive,如何重置标头?

时间:2018-03-05 11:17:58

标签: c++ stream compression 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)。据我所知,由于压缩算法的内部工作,可能无法在内部解压缩数据,并且除了libarchive内部缓冲区中有限数量的字节外,数据不会存储在任何地方。

我们的想法是重置所有内容,并读取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 个答案:

答案 0 :(得分:0)

Libarchive文档,更确切地说,是wishlist in libarchive wiki on GitHub says:

  

有些人要求有效地重新阅读&#34;   特定的档案条目。这是一个棘手的主题。对于很多   格式,从中获得的性能提升非常适中。对于   例如,有一点性能工作,寻求Zip阅读器可以   从一开始就支持非常快速的重读,因为它只涉及到   重新解析中心目录。有真实的情况   收益(例如,tar.gz)将很难处理。该   最可能的实现是某种形式的检查点,以便   客户端可以显式请求检查点对象然后还原   回到那个检查站。如果你,检查点对象可能很复杂   在格式处理程序中有一系列堆叠的读取过滤器和状态   本身。

我认为在libarchive的帮助下在档案馆中寻找目前是不可能的,所以我的问题的解决方案是只有在怀疑我想要重新读取它时才能记住所有读取数据,并且推动它回流。