是否可以将std :: basic_ifstream和std :: basic_ofstream与自定义缓冲区一起使用?

时间:2018-09-09 16:19:23

标签: c++

我不知道,是否可以将std :: basic_ifstream和std :: basic_ofstream与std :: basic_filebuf的自定义实现一起使用?

以64KB大小的块读取文件并内部检查该块的某些哈希值的输入文件流的实现有多复杂?例如,如果散列无效,则抛出hash_exception。输出文件流将块和哈希值写入其后。

我找到了一些创建std :: ifstream的示例,然后创建了另一个从中读取并进行其他处理的流:

std::ifstream infile("test.img");
decompress_stream in(infile, 288);
char data[144 * 128];
in.read(data, 144 * 128);
infile.close();

但是起初我希望它应该是这样的(没有额外的信息流):

std::ifstrem in;
in.setbuffer(new MyBuffer());
in.read();

MyBuffer::underflow()
{
     //read from original buffer
     if (hash != calculated_sash) throw curruption_exception();
     //return the data with omitted hash.
}

这可能吗?

2 个答案:

答案 0 :(得分:2)

文件流对象实际上是std::basic_filebufstd::basic_[io]stream的组合。流接口允许通过std::basic_streambuf方法访问rdbuf()。因此,您可以 将文件流流缓冲区替换为另一个。但是,它与原始文件缓冲区没有任何关系。

由于您拥有的流缓冲区是过滤流缓冲区,因此可以合理地用流构造它,并让构造函数注入过滤器,即类似这样的东西(我省略了模板,因为这些模板与此无关讨论,但可以轻松添加):

class filterbuf
    : public std::streambuf {
    std::istream* istream = nullptr;
    std::ostream* ostream = nullptr;
    std::streambuf * sbuf;

    // override virtual functions as needed
public:
    explicit filterbuf(std::istream& in)
        : istream(&in)
        , sbuf(istream->rdbuf(this)) {
    }
    explict filterbuf(std::ostream& out)
        : ostream(&out)
        , sbuf(ostream->rdbuf(this)) {
    }
    explicit filebuf(std::iostream& inout)
        : istream(&inout)
        , sbuf(istream->rdbuf(this)) {
    }
    ~filebuf() {
        istream && istream->rdbuf(sbuf);
        ostream && ostream->rdbuf(sbuf);
    }
};

在析构函数中还原流缓冲区的要点是std::ostream析构函数在对象上调用flush(),并且自定义流缓冲区到那时就消失了。

过滤器将像这样使用:

std::istream fin(“whatever”);
filterbuf        buf(fin);
if (fin >> whatever) {
    ...
}

答案 1 :(得分:0)

如果要自定义iostream的行为,最简单的方法是使用boost::iostreams。您的用例可能被实现为InputfilterOutputFilter,您可以使用basic_file_sourcebasic_file_sink来读写文件。