我正在解压缩大文件,包含指定的压缩数据块的各种方式。 我写了以下代码:
// input_file - path to file
std::ifstream file(input_file, std::ios_base::in | std::ios_base::binary);
//move to begin of n-th data block, compressed by zlib
file.seekg(offset, std::ios_base::beg);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(file);
// write decompressed data to output file
boost::iostreams::copy(in, output);
我的理解是这一行
boost::iostreams::copy(in, output);
将开始解压缩并复制数据,直到文件结束,在这种情况下这是不需要的。
重要的是,我知道压缩数据的正确偏移量和长度。
Boost文档说:
Source的模型可以定义如下:
struct Source {
typedef char char_type;
typedef source_tag category;
std::streamsize read(char* s, std::streamsize n)
{
// Read up to n characters from the input
// sequence into the buffer s, returning
// the number of characters read, or -1
// to indicate end-of-sequence.
}
};
我想继承ifstream类,覆盖它的read方法,并在该方法内部计算读取的字节数,如果该块中没有更多数据则返回-1,但遗憾的是,它似乎无效。
我写道:
class ifstream_t : public std::ifstream{
public:
ifstream_t(const std::string& fp, std::ios_base::openmode mode = std::ios_base::in) : std::ifstream(fp, mode){}
std::streamsize read(char* s, std::streamsize n) {
// calculate remaining bytes
return -1;
}
};
并将其用于:
ifstream_t file(this->fp, std::ios_base::in | std::ios_base::binary);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(file);
boost::iostreams::copy(in, output);
方法读取,来自我的类,未调用。
答案 0 :(得分:0)
我的理解是这一行
boost::iostreams::copy(in, output);
将开始解压缩并复制数据,直到文件结束,在这种情况下这是不需要的。
我刚试过这个,事实并非如此。解压缩器在压缩数据完成时正确检测流的结束。
我创建了一个包含自己压缩源的随机数据的文件:¹
(dd if=/dev/urandom bs=1 count=$((0x3214a)); cat main.cpp | zlib-flate -compress; dd if=/dev/urandom bs=1 count=$((0x3214a))) > input.txt
使用带有硬编码偏移的程序和该文件时:
<强> Live On Coliru 强>
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <fstream>
#include <iostream>
int main() {
static std::string const input_file = "input.txt";
static size_t const offset = 0x3214a;
std::ostream& output = std::cout;
// input_file - path to file
std::ifstream file(input_file, std::ios_base::in | std::ios_base::binary);
//move to begin of n-th data block, compressed by zlib
file.seekg(offset, std::ios_base::beg);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(file);
// write decompressed data to output file
boost::iostreams::copy(in, output);
}
很高兴再现自己的来源,你可以看到coliru上的直播
coliru上没有python -c 'import zlib; import sys; sys.stdout.write(zlib.compress(sys.stdin.read()))'