我正在尝试通过利用来即时压缩使用Boost Log库创建的日志文件boost::iostreams::gzip_compressor
.因此,当我打电话时BOOST_LOG()
,输出会即时压缩.这是我到目前为止所尝试的:
#include#include #include #include #include #include #include #include #include #include #include #include #include void init() { // Construct the sink typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend > text_sink; boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >(); boost::shared_ptr< std::ofstream > file = boost::make_shared< std::ofstream >( "sample.gz", std::ios_base::out | std::ios_base::binary ); boost::iostreams::filtering_ostream out; out.push( boost::iostreams::gzip_compressor() ); out.push( *(file.get()) ); for( int i = 0; i < 10; i++ ) { out << "Hello world! " << i << std::endl; // compresses OK } sink->locked_backend()->add_stream( file ); // Register the sink in the logging core boost::log::core::get()->add_sink( sink ); } int main( ) { init(); boost::log::sources::logger lg; for( int i = 0; i < 10; i++ ) BOOST_LOG(lg) << "Bye world!" << std::endl; // Does not compress return 0; }
我觉得我应该以某种方式1)将整个filtering_ostream作为接收器,而不仅仅是file
或
2)以某种方式推动记录器接收器而不是file
在filtering_ostream
.
有人能指出我正确的方向吗?谢谢!
我想你想传递filtering_ostream
你的记录器流.你需要做两件事:
制作一个shared_ptr
包含你的filtering_ostream
,和
确保延长输出文件流的生命周期,直到关闭过滤流.
您可以使用自定义shared_ptr
删除器来完成此操作.删除器是传递给shared_ptr
构造函数的可选函数对象,将被调用以释放指针.您可以在删除器中存储一个shared_ptr
to file
,以确保文件存在,只要该流存在.在C++ 11中,你可以使用这样的lambda:
boost::shared_ptr<boost::iostreams::filtering_ostream> out( new boost::iostreams::filtering_ostream, [file](std::ostream *os) { delete os; }); out->push(boost::iostreams::gzip_compressor()); out->push(*file); sink->locked_backend()->add_stream(out);
[file]
lambda 的一部分保持一直shared_ptr
到ofstream
调用删除器.
如果你没有C++ 11编译器,你可以用普通的仿函数做同样的事情,比如(未编译和未经测试):
struct MyDeleter { boost::shared_ptr<std::ofstream> file_; MyDeleter(const boost::shared_ptr<std::ofstream>& file) : file_(file) { } void operator()(std::ostream *os) { delete os; } }; ... boost::shared_ptr<boost::iostreams::filtering_ostream> out( new boost::iostreams::filtering_ostream, MyDeleter(file));