[iostreams] Some basic questions about filtering_stream

Some basic questions about Boost filtering_streams. I have dozens of functions that presently take a parameter of std::ofstream&. For example: void foo(std::ofstream& outStream) { // lots of operations, like this: outStream << "various bits of text"; } Which then get used as thus: void StreamSomeTextToFile(char* fileName) { ofstream myFileStream(fileName, ios::out | ios::app | ios::binary); foo(myFileStream); myFileStream.close(); } Now I'd like to use the boost filtering_stream to output to a compressed ZIP file. I've compiled, linked and run the commonly cited boost filtering_stream test code for packing and unpacking and it worked perfectly for me. Now I'd like to try to substitute my use of std::ofstream& with the 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(); } THREE QUESTIONS: 1) Do all my functions that previously accepted std::ofstream& outStream need to now accept a parameter of type boost::iostreams::filtering_streambuf<boost::iostreams::output>& ? Or, is there a proper parameter type so those numerous ("foo") functions could work with EITHER type of stream type? 2) In my simple test cases, I was not able to use stream operator syntax with the filtering_streambuf: myCompressedFileStream << "some text"; this generated the the error: no match for 'operator<<'. I similarly had compile errors with 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`' Could this be a missing header? If so, I haven't been able to determine which one. 3) In the common test case example code (below), I was confused that I could not locate the file "hello.z" after it had been created. The unpack code (also below) executed correctly and clearly references the created file -- so where can it be found? 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); } My code is being developed on XCode 3.2.6, GNU 4.0, Mac OS X 10.6.8

> Gesendet: Donnerstag, 25. Juli 2013 um 02:41 Uhr
Von: "Stephen Greenfield" <StephenG@screenplay.com> An: "boost-users@lists.boost.org" <boost-users@lists.boost.org> Betreff: [Boost-users] [iostreams] Some basic questions about filtering_stream Some basic questions about Boost filtering_streams. I have dozens of functions that presently take a parameter of std::ofstream&. For example: void foo(std::ofstream& outStream) { // lots of operations, like this: outStream << "various bits of text"; } Which then get used as thus: void StreamSomeTextToFile(char* fileName) { ofstream myFileStream(fileName, ios::out | ios::app | ios::binary); foo(myFileStream); myFileStream.close(); } Now I'd like to use the boost filtering_stream to output to a compressed ZIP file. I've compiled, linked and run the commonly cited boost filtering_stream test code for packing and unpacking and it worked perfectly for me. Now I'd like to try to substitute my use of std::ofstream& with the 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(); } THREE QUESTIONS: 1) Do all my functions that previously accepted std::ofstream& outStream need to now accept a parameter of type boost::iostreams::filtering_streambuf<boost::iostreams::output>& ? Or, is there a proper parameter type so those numerous ("foo") functions could work with EITHER type of stream type? 2) In my simple test cases, I was not able to use stream operator syntax with the filtering_streambuf: myCompressedFileStream << "some text"; this generated the the error: no match for 'operator<<'. I similarly had compile errors with 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`' Could this be a missing header? If so, I haven't been able to determine which one. 3) In the common test case example code (below), I was confused that I could not locate the file "hello.z" after it had been created. The unpack code (also below) executed correctly and clearly references the created file -- so where can it be found?
to 1: Make your functions take a std::ostream& reference, that way you are not bound to the streamtype. to 2: A streambuf is not a stream, its a buffer for a stream, please consult the documentation for usage :) to 3: if you do not specify a concrete path, afaik the file should be created in the directory where the file is run from. kind regards, Jens Weller

Jens,
to 1: Make your functions take a std::ostream& reference, that way you are not bound to the streamtype.
to 2: A streambuf is not a stream, its a buffer for a stream, please consult the documentation for usage :)
Many thanks -- I see that now. However, there is a mysterious piece of this puzzle that still eludes me: Since the filtering_streambuf (myCompressedFileStream) needs the ofstream file (myFileStream) defined FIRST, in order to push it, how do I then construct a valid ostream that I can stream to and will be compressed INTO the file I specified in the ofstream. If I just output to myFileStream, it doesn't go through the filtering_streambuf and UNCOMPRESSED text ends up in the file.
to 3: if you do not specify a concrete path, afaik the file should be created in the directory where the file is run from.
I found the location where the file was being created: <user>/Library/Preferences/<app's preferences folder>. Because the path wasn't specified in the test case of "hello.z", it might be because that was the last folder/directory navigated to by the app's code. I didn't originally find it because normally Spotlight doesn't search those folders. However, Activity Monitor revealed hello.z as an open file -- complete with path! Stephen
participants (2)
-
Jens Weller
-
Stephen Greenfield