I need to open a file as ofstream and write to the front of the file, while preserving the remaining contents of the file, which will be "moved". Similar to "prepend" a file.
Is this possible using the STL or boost ?
I need to open a file as ofstream and write to the front of the file, while preserving the remaining contents of the file, which will be "moved". Similar to "prepend" a file.
Is this possible using the STL or boost ?
No it isn't. And this has been asked here many times before. If you want to do this you have to create new file, write the "prepend" data to it, then open the existing file and copy its contents to the new file.
No -- the language (or library) doesn't really make much difference here. Most file systems just don't allow it, full stop.
The usual way to get the same effect is to write your new data to a new file, then copy the data in the old file to the new file following the data you wrote.
A new iostream
class can wrap that functionality. This assumes your prepend data isn't too large to comfortably fit in memory. Use it like a regular ofstream
.
#include <fstream>
#include <sstream>
#include <vector>
class prepend_ofstream
: public std::ostringstream {
std::filebuf file;
public:
prepend_ofstream() {}
prepend_ofstream( char const *name, openmode mode = out ) {
open( name, mode );
}
~prepend_ofstream() {
if ( is_open() ) close();
}
void open( char const *name, openmode mode ) {
if ( ! file.open( name, mode & binary | in | out ) ) {
setstate( failbit );
}
}
bool is_open() { return file.is_open(); }
void close() {
if ( ! is_open() ) {
setstate( failbit );
return;
}
char *strbuf = &str()[0];
std::vector<char> buf( str().size() );
int rdsz;
do {
rdsz = file.sgetn( &buf[0], buf.size() );
file.pubseekoff( -rdsz, cur );
file.sputn( strbuf, buf.size() );
file.pubseekoff( 0, cur ); // "update the output sequence"
std::copy( &buf[0], &buf[0]+rdsz, strbuf );
} while ( rdsz == buf.size() );
file.sputn( &buf[0], rdsz );
if ( ! file.close() ) {
setstate( failbit );
}
}
};
Typically features are added through new stream buffer classes, not actual streams, but in this case the new functionality is in close
, which is unfortunately not virtual.