2014-06-08 7 views
3

boost::iostreams::gzip_compressor을 사용하여 즉시 부스트 로그 라이브러리를 사용하여 만든 로그 파일을 압축하려고합니다. 따라서 BOOST_LOG()으로 전화하면 출력이 즉석에서 압축됩니다. 여기에 지금까지 시도 무엇 : 나는 어떻게 든 하나 1) 싱크 전체 filtering_ostream을 두어야 느낌, 바로 file 또는압축기 사용 방법 Boost :: Iostreams 필터를 Boost :: Log의 싱크대로 사용하십시오.

2) 어떻게 든 로거 싱크를 밀어 대신하지를 얻을 수

#include <fstream> 
#include <iostream> 

#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filtering_streambuf.hpp> 
#include <boost/iostreams/stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp> 

#include <boost/smart_ptr/shared_ptr.hpp> 
#include <boost/smart_ptr/make_shared_object.hpp> 

#include <boost/log/core.hpp> 
#include <boost/log/trivial.hpp> 
#include <boost/log/sinks/sync_frontend.hpp> 
#include <boost/log/sinks/text_ostream_backend.hpp> 
#include <boost/log/sources/logger.hpp> 

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; 
} 

filtering_ostreamfile이 있습니다.

나를 올바른 방향으로 안내 할 수 있습니까? 감사!

답변

5

로거 스트림으로 filtering_ostream을 전달하고 싶습니다.

  1. filtering_ostream 포함하는 shared_ptr을 확인하고
  2. 는 필터링 스트림이 닫힐 때까지 출력 파일 스트림의 수명이 연장되어 있는지 확인합니다 : 당신은 두 가지 일을해야 할거야.

사용자 정의 shared_ptr 삭제기를 사용하면이 작업을 수행 할 수 있습니다. deleter는 shared_ptr 생성자에 전달 된 선택적 함수 객체이며 포인터를 해제하기 위해 호출됩니다. 삭제기에 shared_ptrfile에 저장하여 스트림이 존재하는 한 파일이 존재하는지 확인할 수 있습니다. C++ 11에서는이 같은 람다와 함께 수행 할 수 있습니다 Deleter가 호출 될 때까지

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] 부분은 ofstreamshared_ptr를 유지합니다. 이 개 작업 솔루션을 제공하기 위해

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)); 
+0

+1 : 당신이 C++ 11 컴파일러가없는 경우

, 당신은, 일반 펑로 (컴파일되지 않은 및 검증되지 않은) 같은 것을 같은 일을 할 수 있습니다 :) – tank