Suppose I have an ifstream
which represents a large file containing lots of sub-files aggregated together. I want to be able to create a "sub" istream
from the larger ifstream
(given a size and offest) representing a part of the file so other code can read from that substream as if it was an independent istream
.
Any ideas on how I might accomplish this?
EDIT - I would prefer to avoid boost.
Just a little idea : If you have control over the client side of the code (i.e. the part that uses the input stream), I suggest you modify it to accept two additional parameters, like illustrated below :
Can become :
I've done something like this using the Boost.Iostreams library. Look under Tutorial|Writing Devices. The idea is to create a "device" class which implements the low-level interface (read/write/seek) and then instantiate an istream/ostream derived class using your device class to do the actual I/O.
This is an example of a streambuf "filter" that reads from a contained streambuf starting at a specified location and reading up to a specified size. You create
substreambuf
, passing your originalstreambuf
in andsubstreambuf
then translates access so that everything is read from the desired location in the underlyingstreambuf
.Most of the overhead involved in calling
sgetc
andsnextc
fromunderflow
anduflow
should optimize away. Many extraction operators work byte by byte, so there should not be additional overhead beyond maintaining the read position within the subsection and checking for the end of the subsection. Of course, reading large chunks of data will be less efficient with this class (although that could be fixed).This still needs improvements like testing that the requested location is within the underlying
streambuf
.It can be used like this
This was inspired by Filtering Streambufs
All iostreams put most of their custom logic in their
streambuf
specializations.fstream
(orbasic_fstream
) initializesistream
with an instance offile_buf
. Same forstringstream
(stringbuf
). If you want to roll your own substream stream, you can do it by implementing your ownstreambuf
in terms of a parent stream.