I\'m currently implementing a ping/pong buffering scheme to safely write a file to disk. I\'m using C++/Boost on a Linux/CentOS machine. Now I\'m facing the problem to force
Not in standard C++. You'll have to use some sort of system specific
IO, like open with the O_SYNC flag under Unix, and then write.
Note that this is partially implicit by the fact that ostream (and in
C, FILE*) are buffered. If you don't know exactly when something is
written to disk, then it doesn't make much sense to insist on the
transactional integrity of the write. (It wouldn't be too hard to
design a streambuf which only writes when you do an explicit flush,
however.)
EDIT:
As a simple example:
class SynchronizedStreambuf : public std::streambuf
{
int myFd;
std::vector myBuffer;
protected:
virtual int overflow( int ch );
virtual int sync();
public:
SynchronizedStreambuf( std::string const& filename );
~SynchronizedStreambuf();
};
int SynchronizedStreambuf::overflow( int ch )
{
if ( myFd == -1 ) {
return traits_type::eof();
} else if ( ch == traits_type::eof() ) {
return sync() == -1 ? traits_type::eof() : 0;
} else {
myBuffer.push_back( ch );
size_t nextPos = myBuffer.size();
myBuffer.resize( 1000 );
setp( &myBuffer[0] + nextPos, &myBuffer[0] + myBuffer.size() );
return ch;
}
}
int SynchronizedStreambuf::sync()
{
size_t toWrite = pptr() - &myBuffer[0];
int result = (toWrite == 0 || write( myFd, &myBuffer[0], toWrite ) == toWrite ? 0 : -1);
if ( result == -1 ) {
close( myFd );
setp( NULL, NULL );
myFd = -1;
} else {
setp( &myBuffer[0], &myBuffer[0] + myBuffer.size() );
}
return result;
}
SynchronizedStreambuf::SynchronizedStreambuf( std::string const& filename )
: myFd( open( filename.c_str(), O_WRONLY | O_CREAT | O_SYNC, 0664 ) )
{
}
SynchronizedStreambuf::~SynchronizedStreambuf()
{
sync();
close( myFd );
}
(This has only been superficially tested, but the basic idea is there.)