I’m trying to update a random-access binary file using the std::iostream interface with separate get/put positions managed via seekg/seekp. Everything works fine with stringstream, but when I create a file descriptor-based stream using Boost.Iostream (specifically boost::iostreams::stream<boost::iostreams::file_descriptor>), the get/put positions are no longer independent.
I gather from the documentation on Modes that what I’m looking for is a “Dual-seekable” stream. The docs show that Mode is a template parameter of stream, “principally for internal use”, but this seems to be (no longer?) correct. Instead, the mode (aka category?) is taken directly from the Device:
template< typename Device,
typename Tr = ...,
typename Alloc = ...>
struct stream : detail::stream_base<Device, Tr, Alloc> {
public:
typedef typename char_type_of<Device>::type char_type;
struct category
: mode_of<Device>::type,
closable_tag,
detail::stream_traits<Device, Tr>::stream_tag
{ };
Primary question: Is there some way to get Dual-seekable behavior from a Device such as file_descriptor (which is tagged Seekable but not Dual-seekable)?
Secondary question: Are there any general guarantees about the independence of seekg/seekp? I gather from web searches that stringstream seems to be independent, but that fstream may not be. However, I can’t find anything authoritative.
If you construct a bidirectional_seekable
boost::iostreams::deviceit will support two separate get/put positions which can be modified with the help of theiostreams::seekfunction.Roughly, this will look like:
You need to implement your stream logic by filling out the three functions (read, write, seek), see the examples and documentation for details. The important point for you is the parameter
std::ios::openmode whichgiving you a clue which of the positions (read, write, or both) you need to update.Now you use this device while instantiating an boost::iostreams::stream:
where s is your stream instance you can use to do the require file operations.