c++ 为什么使用boost::iostream::zlib_compressor的boost::iostream::filtering_ostream需要被销毁才能写入接收器?

xxe27gdn  于 2022-12-27  发布在  iOS
关注(0)|答案(1)|浏览(230)

在今天花了相当长的时间调试这个问题之后,我注意到需要销毁boost::iostream::filtering_ostream才能写入接收器。
试验代码:

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/zlib.hpp>

#include <sstream>

struct ZlibOstream : boost::iostreams::filtering_ostream
{
    ZlibOstream(std::ostream& os)
    {
        boost::iostreams::filtering_ostream::push(boost::iostreams::zlib_compressor{});
        boost::iostreams::filtering_ostream::push(os);
    }
};

int main()
{   
    std::ostringstream oss;
    
    #ifdef HAS_SCOPE
    {
    #endif
    
    ZlibOstream zlibOstream{oss};
    
    zlibOstream << "This is a test string.\n";
    
    #ifdef HAS_SCOPE
    }
    #endif
    
    return (oss.tellp() == 0);
}

调用flush()不起作用,当我删除zlib_compressor时,我不需要这样做。
Coliru的结果:https://coliru.stacked-crooked.com/a/7cd166d2d820e838
这种行为背后的原因是什么?

pqwbnv8z

pqwbnv8z1#

这实际上与这个问题有关:
Flushing a boost::iostreams::zlib_compressor. How to obtain a "sync flush"?
您需要调用boost::iostreams::zlib_compressor::close才能进行刷新。
您可以通过在boost::iostream::filtering_ostream上调用pop()reset()来实现这一点。
请注意,pop()的名称建议弹出链中的最后一个过滤器,然后reset()完全清除链,这样filtering_ostream以后就无法使用了。
示例:

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/zlib.hpp>

#include <sstream>

struct ZlibOstream : boost::iostreams::filtering_ostream
{
    ZlibOstream(std::ostream& os)
    {
        boost::iostreams::filtering_ostream::push(boost::iostreams::zlib_compressor{});
        boost::iostreams::filtering_ostream::push(os);
    }
};

int main()
{   
    std::ostringstream oss;

    ZlibOstream zlibOstream{oss};

    zlibOstream << "This is a test string.\n";

    zlibOstream.reset(); // needed if you want to write to oss

    return oss.tellp();
}

相关问题