He estado usando std::istream
y ostream
como una interfaz polimórfica de acceso aleatorio binario de E/S en C++, pero parece subóptima de muchas maneras:Recomendaciones para un C++ polimórfica, interfaz reubicable, me binaria/S
- Las búsquedas de 64 bits no son portátiles y son propensas a errores debido a las limitaciones de streampos/streamoff; Actualmente el uso de boost/iostreams/positioning.hpp como una solución, pero requiere vigilancia
- operaciones ausentes tales como truncar o extender un archivo (ala POSIX
ftruncate
) - inconsistencia entre implementaciones concretas; p.ej.
stringstream
tiene posiciones get/put independientes, mientras quefilestream
no - Inconsistencia entre implementaciones de plataforma; p.ej. comportamiento de búsqueda de pasar el final de un archivo o el uso de
failbit
/badbit
de errores - no necesitan todas las instalaciones de formato de
stream
o posiblemente incluso el almacenamiento temporal destreambuf
streambuf
informe de errores (es decir, excepciones y recurrentes de una indicador de error) es supuestamente implementation-dependent en la práctica
me gusta la interfaz simplificada proporcionada por el Boost.Iostreams Device concept, pero se proporciona como plantillas de función en lugar de una clase polimórfico. (Hay un device
class, pero no es polimórfico y es solo una clase de ayuda de implementación no necesariamente utilizada por las implementaciones de dispositivos suministrados.) Principalmente uso archivos de disco grandes, pero realmente quiero el polimorfismo para poder sustituir fácilmente las implementaciones alternativas (por ej. use stringstream
en lugar de fstream
para pruebas unitarias) sin toda la complejidad y el acoplamiento en tiempo de compilación de la creación de instancias de plantillas profundas.
¿Alguien tiene alguna recomendación de un enfoque estándar para esto? Parece una situación común, así que no quiero inventar mis propias interfaces innecesariamente. Como ejemplo, algo como java.nio.FileChannel parece ideal.
Mi mejor solución hasta el momento es poner una fina capa polimórfica encima de los dispositivos Boost.Iostreams. Por ejemplo:
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;
};
Gracias por el puntero, me había olvidado de Qt. No quiero tomar una dependencia de él, pero proporciona cierta perspectiva. –