用于将boost filtering_stream替换为std :: ofstream的Param语法

时间:2013-07-24 20:48:56

标签: c++ boost zlib boost-iostreams

有关boost filtering_streams的一些基本问题。我有很多函数采用std :: ofstream&

的参数
void foo(std::ofstream& outStream)
{
    // lots of operations, like this:
    outStream << "various bits of text";
}

void StreamSomeTextToFile(char* fileName)
{
    ofstream myFileStream(fileName, ios::out | ios::app | ios::binary);
    foo(myFileStream);
    myFileStream.close();
}

现在我想使用boost filtering_stream输出到压缩的ZIP文件。通常引用的boost filtering_streams测试代码用于打包,解压缩编译,链接,并且完美适合我。我想替换filtering_stream:

void StreamSomeCompressedTextToFile(char* fileName)
{
    ofstream myFileStream(destPath, std::ios_base::out | std::ios_base::app | std::ios_base::binary);
    boost::iostreams::filtering_streambuf<boost::iostreams::output> myCompressedFileStream;
    myCompressedFileStream.push(boost::iostreams::zlib_compressor());
    myCompressedFileStream.push(myFileStream);

    foo(myCompressedFileStream);    // I can't just pass myCompressedFileStream to foo(std::ofstream&), right?
    myFileStream.close();
}

三个问题:

1)执行以前接受过std :: ofstream&amp;的所有功能。 outStream现在需要接受boost :: iostreams :: filtering_streambuf&amp;类型的参数。 ?或者是否有适当的参数类型,因此那些众多(“foo”)函数可以使用EITHER类型的流类型?

2)在我的简单测试用例中,我无法将流操作符语法与filtering_streambuf一起使用:

myCompressedFileStream << "some text";

这产生了错误:'operator&lt;&lt;'不匹配。我同样使用write()编译错误:

error: 'class boost::iostreams::filtering_streambuf<boost::iostreams::output, char, std::char_traits<char>, std::allocator<char>, boost::iostreams::public_>' has no member named 'write

3)在常见的测试用例示例代码(下面)中,我很困惑,在创建文件后找不到文件“hello.z”。解压缩代码(也在下面)清楚地引用它 - 那么在哪里可以找到它?注意:最终发现了位置:它位于/ Library / Preferences /

void pack()
{            
    std::ofstream file("hello.z", std::ios_base::out | std::ios_base::binary);

    boost::iostreams::filtering_streambuf<boost::iostreams::output> out;
    out.push(boost::iostreams::zlib_compressor());
    out.push(file);       
    char data[5] = {'a', 'b', 'c', 'd', 'e'};    
    boost::iostreams::copy(boost::iostreams::basic_array_source<char>(data, sizeof(data)), out);
    file.close();
}

void unpack()
{
    std::fstream file("hello.z", 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, std::cout);
}

BTW:XCode 3.2.6,GNU 4.0,OS X 10.6.8

2 个答案:

答案 0 :(得分:3)

按顺序提问:

1:流缓冲区对象(如boost :: iostream :: filtering_streambuf或std :: streambuf)不能与流对象互换(例如std :: ostream或boost的实现)。话虽这么说,你可以将像“myCompressedFileStream”这样的streambuf对象传递给ostream对象的构造函数(this boost iostream tutorial通过示例提供了一个不错的解释)。并且因为boost的streambufs与标准库中的streambufs兼容,所以您无需更改任何接受std :: ostream / ofstream引用的函数。你不能将streambufs作为流传递。

2:与上面相同,插入运算符是为流而不是streambuf定义的。

3:通常,在可执行文件的目录中创建没有前面目录名的文件。话虽这么说,我发现有时候Finder反映了由非Finder进程更新/创建的文件有点慢。我没有在使用ls的终端中遇到这些问题。不过,不知道这是否与你的问题有关。

答案 1 :(得分:2)

SUCCESS!

Paul Schellin(上图)和Boost用户的一些提示得到了答案:

1)Boost用户Frédéric指出“在output_file [filtering_ostream]被破坏之前没有任何事情发生。所以请附在{}”中。这是 基本缺失的部分 ,因为我试图在我的ofstream上执行file.close(),直到我的filtering_streambuf被销毁。这解释了为什么文件是空的!

重新阅读文件透露:

  "By default, if the Device at the end of the chain is popped
   or if the filtering_stream is complete when it is destroyed,
   all the filters and devices in the chain are closed using the
   function close. This behavior can be modified using the member
   function set_auto_close"

这种状态是不需要从filtering_stream的堆栈中“弹出”compress()或ofstream(文件),也不需要调用close()。只需破坏filtering_stream对象,一切都会被写出并清理干净。一个模糊的细节,与人们可能期望的相反。

3)Boost用户Holger Gerth质疑我在使用filtering_stream时使用filtering_streambuf的原因。事实是,我不确定,但是,在我的实验中,我既不能从filtering_stream构造ostream(我需要传递给其他函数),也不能通过filtering_stream来代替我需要的ostream。

即使在阅读了有关filtering_streambuf vs filtering_stream的几篇文章之后,我仍然不知道如何以及为什么(为了我的目的)我会使用filtering_stream而不是从filtering_streambuf构造一个ostream。

所以,回收:

1)从filtering_streambuf构造一个单独的ostream,并将THAT传递给foo()或传递给Stream Insertion操作符(即&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

2)不要调用myFileStream.close();

相关问题