Syntax parameter to substitute boost filtering_stream for std :: ofstream

Some basic questions about stream_flow filtering optimization. I have dozens of functions that take the std :: ofstream & parameter

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

Now I would like to use boost filtering_stream to output to a compressed ZIP file. The often quoted test code boost filtering_streams for packaging and unpacking is compiled, linked, and works great for me. I would like to replace 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) Perform all of my functions that previously took std :: ofstream & outStream should now accept a parameter like boost :: iostreams :: filtering_streambuf &? Or is there a valid parameter type so that these numerous ("foo") functions can work with a type of type ETHER?

2) In my simple test cases, I was unable to use the stream operator syntax with filtering_streambuf:

 myCompressedFileStream << "some text"; 

this generated an error: there is no match for 'operator <<'. I also had compilation 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

3) In the general test case example (below), I was confused by the fact that I could not find the file "hello.z" after creating it. The unpack code (also below) explicitly refers to it - so where can I find it? NOTE: the location was finally discovered: it was in / 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

+4
source share
2 answers

Taking questions in order:

1: stream buffer objects (such as boost :: iostream :: filtering_streambuf or std :: streambuf) are not interchangeable with stream objects (e.g. std :: ostream or boost). With this, you can pass a streambuf object, such as "myCompressedFileStream", into the constructor of the ostream object ( this iostream accelerator gives a worthy explanation with Examples). And since boost stream boost files are compatible with versions of the standard library, you do not need to change any functions that accept std :: ostream / ofstream links. You simply cannot pass streambufs as streams.

2: Same as above, the insert statement is defined for streams, not streambufs.

3: Usually files that do not have a previous directory name are created in the executable file directory. In doing so, I sometimes found that Finder was somewhat slow in reflecting files updated / created by processes other than Finder. I did not experience these problems in the terminal using ls. I don’t know if this is related to your problem.

+3
source

SUCCESS!

A combination of prompts from Paul Schellin (above) and several Boost users led to the answer:

1) The Boost User Frédéric indicated that “nothing will happen until the output_file [filtering_ostream] file is deleted. Therefore, enclose in {}”. This was a necessary missing item because I tried to do file.close () in my stream before my filtering_streambuf was destroyed. This explains why the file is empty!

Re-reading the documentation shown:

  "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" 

This means that there is no need to “push” the compressor () or stream (file) from the filtering_stream stack or call the close () function. Just destroy the filtering_stream object and everything will be written out and cleared. An unclear detail, and this contradicts what can be expected.

3) Boost User Holger Gerth asked why I used filtering_streambuf when I could use filtering_stream. True, I was not sure, however, in my experiments I could neither build ostream (which I had to pass to other functions) from filtering_stream, I could not pass filtering_stream instead of the stream you needed.

Even after reading several articles on filtering_streambuf vs filtering_stream, I am still puzzled by how and why (FOR MY PURPOSE) I would use filtering_stream to build an ostream from filtering_streambuf.

SO, TO RECAP:

1) Create a separate stream from the filter_streambuf filter and pass THAT to foo () or to the Stream Insertion statement (i.e. <).

2) Do not call myFileStream.close ();

+2
source

Source: https://habr.com/ru/post/1493304/


All Articles