2010-06-15 15 views
5

C++ Sto usando std::istream e ostream come interfaccia polimorfica per l'accesso casuale binario di I/O in C++, ma sembra non ottimale in molti modi:Raccomandazioni per un polimorfico, ricercabile, I/O binario interfaccia

  • Le ricerche a 64 bit sono non portatili e soggette a errori a causa di limiti di stream/streamoff; attualmente utilizzando boost/iostreams/positioning.hpp come una soluzione, ma richiede vigilanza
  • operazioni mancanti come troncare o estendere un file (ala POSIX ftruncate)
  • incoerenza tra implementazioni concrete; per esempio. stringstream ha posizioni get/put indipendenti mentre filestream non
  • Incoerenza tra le implementazioni della piattaforma; per esempio. comportamento di cercare passare il fine di un file o l'utilizzo di failbit/badbit sugli errori
  • non hanno bisogno di tutte le strutture di formattazione di stream o forse anche il buffer di streambuf
  • streambuf segnalazione degli errori (vale a dire le eccezioni contro la restituzione di un indicatore di errore) è presumibilmente implementation-dependent in pratica

mi piace l'interfaccia semplificata fornita dal Boost.Iostreams Device concept, ma è disponibile come modelli funzionali piuttosto che una classe polimorfica. (C'è un device class, ma non è polimorfico ed è solo una classe helper di implementazione non necessariamente utilizzata dalle implementazioni di dispositivo fornite.) Uso principalmente file di grandi dimensioni, ma voglio davvero il polimorfismo così posso facilmente sostituire le implementazioni alternative (es. utilizzare stringstream anziché fstream per i test di unità) senza tutta la complessità e l'accoppiamento in fase di compilazione dell'istanza di modello profonda.

Qualcuno ha qualche raccomandazione su un approccio standard a questo? Sembra una situazione comune, quindi non voglio inventare le mie interfacce inutilmente. Ad esempio, qualcosa come java.nio.FileChannel sembra l'ideale.

La mia soluzione migliore finora è mettere uno strato polimorfo sottile sopra i dispositivi Boost.Iostreams. Ad esempio:

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

risposta

0

Ho appena finito con una serie di interfacce astratte simili a quelle che ho delineato nella domanda. Non sembrano esserci standard leggeri e polimorfi per questo ...

1

Hai dato un'occhiata a una classe Qi di QIODevice e sottoclassi? Non sono del tutto sicuro che soddisfi le tue esigenze, ma forse vale la pena provare: QIODevice.

+0

Grazie per il puntatore, mi ero dimenticato di Qt. Non voglio dipendere da esso, ma fornisce una certa prospettiva. –