用 boost 过滤流替换 std::ofstream 的参数语法

SMG*_*eld 6 c++ boost zlib boost-iostreams

关于 boostfiltering_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();
}
Run Code Online (Sandbox Code Playgroud)

现在我想使用 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();
}
Run Code Online (Sandbox Code Playgroud)

三个问题:

1) 我之前接受 std::ofstream& outStream 的所有函数现在都需要接受 boost::iostreams::filtering_streambuf& 类型的参数吗?或者是否有适当的参数类型,以便那些众多(“foo”)函数可以与任何一种类型的流类型一起使用?

2) 在我的简单测试用例中,我无法将流运算符语法与过滤流缓冲区一起使用:

myCompressedFileStream << "some text";
Run Code Online (Sandbox Code Playgroud)

这产生了错误:“operator<<”不匹配。我同样有 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);
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句:XCode 3.2.6,GNU 4.0,OS X 10.6.8

小智 3

按顺序回答问题:

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

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

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