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ährendfilestream
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 vonstreambuf
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;
};
Danke für den Zeiger, ich hatte Qt vergessen. Ich möchte nicht davon abhängig sein, aber es gibt eine Perspektive. –