2010-06-15 25 views
5

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 que filestream 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 de streambuf
  • 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; 
}; 

Respuesta

0

Acabo de terminar con un conjunto de interfaces abstractas similar a lo que describí en la pregunta. No parece haber estándares ligeros, polimórficos para esto ...

1

¿Has echado un vistazo a la clase y subclases de QI's QIODevice? No estoy seguro de si se ajusta a sus necesidades, pero tal vez vale la pena intentarlo: QIODevice.

+0

Gracias por el puntero, me había olvidado de Qt. No quiero tomar una dependencia de él, pero proporciona cierta perspectiva. –

Cuestiones relacionadas