I used std::istreamit ostreamas a polymorphic interface for binary random access I / O in C ++, but it seems suboptimal in different ways:
- 64-bit requests are not portable and error prone due to streaming or streaming restrictions; boost / iostreams / positioning.hpp is currently being used as a workaround, but this requires vigilance.
- Missing operations, such as truncating or file extension (ala POSIX
ftruncate) - Inconsistency between specific implementations; for example,
stringstreamhas independent get / put positions, while filestreamnot - Inconsistency between platform implementations; e.g. search behavior pass end of file or use
failbit/ badbiton errors - You do not need all the formatting tools,
streamor perhaps even bufferingstreambuf streambufan error report (that is, exceptions or an error indicator return) is presumably a Concept of the Boost.Iostreams Device , but it is presented as functional templates, not a polymorphic class. (There is a deviceclass , but it is not polymorphic and is just an auxiliary implementation class, which is not necessarily used by the implementations of the supplied device.) I mainly use large files on disk, but I really need polymorphism, so I can easily replace alternative implementations (for example , use stringstreaminstead fstreamfor unit tests) without any complexity and compilation of time for deep template creation.- ? , . , - java.nio.FileChannel .
- Boost.Iostreams. :
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;
};