I've been using std::istream
and ostream
as a polymorphic interface for random-access binary I/O in C++, but it seems suboptimal in numerous ways:
ftruncate
)stringstream
has independent get/put positions whereas filestream
does notfailbit
/badbit
on errorsstream
or possibly even the buffering of streambuf
streambuf
error reporting (i.e. exceptions vs. returning an error indicator) is supposedly implementation-dependent in practiceI like the simplified interface provided by the Boost.Iostreams Device concept, but it's provided as function templates rather than a polymorphic class. (There is a device
class, but it's not polymorphic and is just an implementation helper class not necessarily used by the supplied device implementations.) I'm primarily using large disk files, but I really want polymorphism so I can easily substitute alternate implementations (e.g. use stringstream
instead of fstream
for unit tests) without all the complexity and compile-time coupling of deep template instantiation.
Does anyone have any recommendations of a standard approach to this? It seems like a common situation, so I don't want to invent my own interfaces unnecessarily. As an example, something like java.nio.FileChannel seems ideal.
My best solution so far is to put a thin polymorphic layer on top of Boost.Iostreams devices. For example:
class my_istream
{
public:
virtual std::streampos seek(stream_offset off, std::ios_base::seekdir way) = 0;
virtual std::streamsize read(char* s, std::streamsize n) = 0;
virtual void close() = 0;
};
template <class T>
class boost_istream : public my_istream
{
public:
boost_istream(const T& device) : m_device(device)
{
}
virtual std::streampos seek(stream_offset off, std::ios_base::seekdir way)
{
return boost::iostreams::seek(m_device, off, way);
}
virtual std::streamsize read(char* s, std::streamsize n)
{
return boost::iostreams::read(m_device, s, n);
}
virtual void close()
{
boost::iostreams::close(m_device);
}
private:
T m_device;
};
Did you have a look an Qt's QIODevice class and subclasses? I'm not quite sure if it fits your needs, but maybe its worth a try: QIODevice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With