2010-06-15 7 views
5

Ich habe std::istream und ostream als polymorphe Schnittstelle für Random-Access binären I/O in C++ verwenden, aber es scheint nicht optimal auf vielfältige Weise:Empfehlungen für eine C++ polymorphe, seekable, binäre I/O-Schnittstelle

  • 64-Bit-Suchvorgänge sind aufgrund von streampos/streamoff-Beschränkungen nicht tragbar und fehleranfällig; zur Zeit als boost/iostreams/positioning.hpp als Behelfslösung, aber es erfordert Wachsamkeit
  • Fehlende Operationen wie Kürzen oder eine Datei (ala POSIX ftruncate)
  • Inkonsistenz zwischen konkreten Implementierungen erstreckt; z.B. stringstream hat unabhängige get/put-Positionen, während filestream nicht
  • Inkonsistenz zwischen Plattformimplementierungen; z.B. Verhalten das Ende einer Datei oder Verwendung failbit/badbit auf Fehler passieren sucht
  • Sie alle Formatierungsmöglichkeiten von stream nicht brauchen oder möglicherweise sogar die Pufferung von streambuf
  • streambuf Fehlerberichterstattung (dh Ausnahmen gegen eine Rückkehr Fehleranzeige) ist angeblich implementation-dependent in der Praxis

ich die vereinfachte Schnittstelle durch die Boost.Iostreams Device concept vorgesehen mögen, aber es ist als Funktionsschablonen eher als eine polymorphe Klasse. (Es gibt eine device class, aber es ist nicht polymorph und ist nur eine Implementierungsklasse, die nicht unbedingt von den mitgelieferten Geräte-Implementierungen verwendet wird.) Ich benutze hauptsächlich große Dateien, aber ich möchte wirklich Polymorphie, so dass ich alternative Implementierungen (z Verwenden Sie stringstream anstelle von fstream für Komponententests) ohne die gesamte Komplexität und Kompilierungszeit Kopplung der tiefen Template Instanziierung.

Hat jemand irgendwelche Empfehlungen für einen Standardansatz? Es scheint eine gemeinsame Situation zu sein, daher möchte ich meine eigenen Schnittstellen nicht unnötig neu erfinden. Als ein Beispiel scheint etwas wie java.nio.FileChannel ideal.

Meine beste Lösung bisher ist es, eine dünne polymorphe Schicht auf Boost.Iostreams Geräte zu setzen. Zum Beispiel:

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; 
}; 

Antwort

0

Ich endete gerade mit einer Reihe von abstrakten Schnittstellen ähnlich wie ich in der Frage skizziert. Es scheint keine leichten, polymorphen Standards dafür zu geben ...

1

Haben Sie sich die QIODevice-Klasse und Unterklassen von Qt angesehen? Ich bin mir nicht ganz sicher, ob es Ihren Bedürfnissen entspricht, aber vielleicht ist es einen Versuch wert: QIODevice.

+0

Danke für den Zeiger, ich hatte Qt vergessen. Ich möchte nicht davon abhängig sein, aber es gibt eine Perspektive. –

Verwandte Themen