[iostreams] Closing a filtering_ostream
How do you close a filtering_ostream object once you have finished
writing to it?
In my program below, I would expect the file "hello.bz2" to have been
written once the close() function has been called, but it is not the
case. The contents are not actually written until I exit the scope in
which the filtering_ostream object is defined (at which point the
destructor presumably does the job). (The file "some_text.txt" contains
just the text "hello world!" so I would expect it not to be written
until the file is closed.)
I would like to be able to do this explicitly and not have to rely on
the destruction of the object - could you explain how can this be done?
Another question: what should the second parameter to close() be? I've
used BOOST_IOS::trunc here, but is there some other more appropriate value?
Thanks,
Paul Giaccone
#include <fstream>
#include <iostream>
#include
Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
I tried calling out.reset() to the filtering_ostream object. This has the desired effect, as the data is written to file before "out" falls out of scope, but then when the end of the scope is reached, my program crashes in the destructor. If this is not the right way to flush the stream, what should I be doing instead? I tried strict_sync() but this returned false because it looks as though the compressor is not flushable (although I could not find anything about this in the documentation). I am working in Visual Studio .NET 7.1. Call stack:
MyProgram.exe!std::locale::locale(const std::locale & _Right={...}) Line 231 + 0x29 C++ MyProgram.exe!std::basic_streambuf
MyProgram.exe!boost::io::basic_ios_locale_saver ::restore() Line 241 + 0x1e C++ MyProgram.exe!boost::io::basic_ios_locale_saver ::~basic_ios_locale_saver MyProgram.exe!boost::archive::basic_text_oprimitive ::~basic_text_oprimitive () Line 105 + 0xf C++ MyProgram.exe!boost::archive::text_oarchive_implboost::archive::text_oarchive::~text_oarchive_implboost::archive::text_oarchive()
Line 72 + 0x80 C++
MyProgram.exe!boost::archive::text_oarchive::~text_oarchive() Line
89 + 0x34 C++
MyProgram.exe!MyClass::save(const
std::basic_string
At 06:37 AM 10/5/2005, you wrote:
Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
Since you've noted that the destructor has the behavior you want, why not put the filtering_ostream in a scoped_ptr and .reset(0) the pointer when you're done with it?
Alan M. Carroll wrote:
At 06:37 AM 10/5/2005, you wrote:
Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
Since you've noted that the destructor has the behavior you want, why not put the filtering_ostream in a scoped_ptr and .reset(0) the pointer when you're done with it?
This is not necessary: pop() and reset() both flush and close the current device and then destroy it. -- Jonathan Turkanis www.kangaroologic.com
Paul Giaccone wrote:
Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
I tried calling out.reset() to the filtering_ostream object. This has the desired effect, as the data is written to file before "out" falls out of scope, but then when the end of the scope is reached, my program crashes in the destructor.
Could you post the program (or a simplified version)? When I add reset() to the program in your previous message, it works fine.
If this is not the right way to flush the stream, what should I be doing instead? I tried strict_sync() but this returned false because it looks as though the compressor is not flushable (although I could not find anything about this in the documentation).
Right, the compressors are not flushable. The purpose of strict_sync() is to allow you to switch filters in the middle of a sequence of i/o operations. With compression, switching filters before all the data is compressed will generally result in garbage, so there's no point trying to implement flush().
Paul Giaccone
-- Jonathan Turkanis www.kangaroologic.com
Jonathan Turkanis wrote:
Paul Giaccone wrote:
Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
I tried calling out.reset() to the filtering_ostream object. This has the desired effect, as the data is written to file before "out" falls out of scope, but then when the end of the scope is reached, my program crashes in the destructor.
Could you post the program (or a simplified version)? When I add reset() to the program in your previous message, it works fine.
If this is not the right way to flush the stream, what should I be doing instead? I tried strict_sync() but this returned false because it looks as though the compressor is not flushable (although I could not find anything about this in the documentation).
Right, the compressors are not flushable. The purpose of strict_sync() is to allow you to switch filters in the middle of a sequence of i/o operations. With compression, switching filters before all the data is compressed will generally result in garbage, so there's no point trying to implement flush().
Thanks for the confirmation, Jonathan. The program I sent in my original posting is the exact program I am testing. It's strange though that reset() should crash for me but not for you. Paul Giaccone
Paul Giaccone wrote:
Jonathan Turkanis wrote:
Paul Giaccone wrote:
If this is not the right way to flush the stream, what should I be doing instead? I tried strict_sync() but this returned false because it looks as though the compressor is not flushable (although I could not find anything about this in the documentation).
Right, the compressors are not flushable. The purpose of strict_sync() is to allow you to switch filters in the middle of a sequence of i/o operations. With compression, switching filters before all the data is compressed will generally result in garbage, so there's no point trying to implement flush().
Thanks for the confirmation, Jonathan. The program I sent in my original posting is the exact program I am testing.
The stack trace you posted looks like it contains some code from Boost.Serialization.
It's strange though that reset() should crash for me but not for you.
Definitely. What compiler options are you using?
Paul Giaccone
-- Jonathan Turkanis www.kangaroologic.com
Jonathan Turkanis wrote:
Paul Giaccone wrote:
Thanks for the confirmation, Jonathan. The program I sent in my original posting is the exact program I am testing.
The stack trace you posted looks like it contains some code from Boost.Serialization.
It's strange though that reset() should crash for me but not for you.
Definitely. What compiler options are you using?
Compile flags: /Od /I "D:\boost\include\boost-1_33" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm /EHsc /RTC1 /MLd /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP Link flags: /OUT:"Debug/CompressionTest.exe" /INCREMENTAL /NOLOGO /LIBPATH:"D:\boost\lib" /DEBUG /PDB:"Debug/CompressionTest.pdb" /SUBSYSTEM:CONSOLE /MACHINE:X86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Browse information (probably not relevant): /nologo No build events; no custom build step. This is a debug version of the program. Paul
Sorry I didn't reply sooner -- I've been away for the last few days. Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
You can use either pop() or reset().
In my program below, I would expect the file "hello.bz2" to have been written once the close() function has been called, but it is not the case. The contents are not actually written until I exit the scope in which the filtering_ostream object is defined (at which point the destructor presumably does the job).
reset() or pop() should work. This also reflects a problem with filtering_ostream which I noticed only after the feature freeze before the 1.33 release: copy calls close() on both its arguments, but close() is a no-op for filtering_streams. Instead, close() should probably call pop().
(The file "some_text.txt" contains just the text "hello world!" so I would expect it not to be written until the file is closed.)
No, the implementation is free to flush the stream at any time. Also, copy closes the stream.
I would like to be able to do this explicitly and not have to rely on the destruction of the object - could you explain how can this be done?
Another question: what should the second parameter to close() be? I've used BOOST_IOS::trunc here, but is there some other more appropriate value?
close() is meant to be called by the iostreams library; you shouldn't have to call it yourself. Thanks for using the iostreams library!
Thanks,
Paul Giaccone
-- Jonathan Turkanis www.kangaroologic.com
Jonathan Turkanis wrote:
Sorry I didn't reply sooner -- I've been away for the last few days.
Paul Giaccone wrote:
How do you close a filtering_ostream object once you have finished writing to it?
You can use either pop() or reset().
In my program below, I would expect the file "hello.bz2" to have been written once the close() function has been called, but it is not the case. The contents are not actually written until I exit the scope in which the filtering_ostream object is defined (at which point the destructor presumably does the job).
reset() or pop() should work.
This also reflects a problem with filtering_ostream which I noticed only after the feature freeze before the 1.33 release: copy calls close() on both its arguments, but close() is a no-op for filtering_streams. Instead, close() should probably call pop().
(The file "some_text.txt" contains just the text "hello world!" so I would expect it not to be written until the file is closed.)
No, the implementation is free to flush the stream at any time. Also, copy closes the stream.
I would like to be able to do this explicitly and not have to rely on the destruction of the object - could you explain how can this be done?
Another question: what should the second parameter to close() be? I've used BOOST_IOS::trunc here, but is there some other more appropriate value?
close() is meant to be called by the iostreams library; you shouldn't have to call it yourself.
I didn't see this message before my earlier reply. Thank you for your detailed explanation of what is happening - it's very useful. Paul Giaccone
Paul Giaccone wrote:
Jonathan Turkanis wrote:
close() is meant to be called by the iostreams library; you shouldn't have to call it yourself.
I didn't see this message before my earlier reply.
That's because I forgot to send it ;-)
Thank you for your detailed explanation of what is happening - it's very useful.
Glad to help.
Paul Giaccone
-- Jonathan Turkanis www.kangaroologic.com
participants (3)
-
Alan M. Carroll
-
Jonathan Turkanis
-
Paul Giaccone