Рекомендации для C ++ полиморфного, доступного для поиска интерфейса двоичного ввода-вывода - PullRequest
5 голосов
/ 16 июня 2010

Я использовал std::istream и ostream в качестве полиморфного интерфейса для двоичного ввода-вывода с произвольным доступом в C ++, но он кажется неоптимальным во многих отношениях:

  • 64-битзапросы являются непереносимыми и подвержены ошибкам из-за ограничений streampos / streamoff;в настоящее время используется boost / iostreams / positioning.hpp в качестве обходного пути, но для этого требуется бдительность
  • Отсутствие таких операций, как усечение или расширение файла (ala POSIX ftruncate)
  • Несоответствие между конкретными реализациями;например, stringstream имеет независимые позиции get / put, тогда как filestream не
  • Несоответствие между реализациями платформы;Например, поведение поиска передается в конец файла или использование failbit / badbit при ошибках
  • Не нужно все средства форматирования stream или, возможно, даже буферизация streambuf
  • streambuf сообщение об ошибке (т.е. исключения и возврат индикатора ошибки) предположительно зависит от реализации на практике

Мне нравится упрощенный интерфейс, предоставляемый Boost.Iostreams Концепция устройства , но она предоставляется в виде шаблонов функций, а не полиморфного класса.(Существует device класс , но он не полиморфный и является просто вспомогательным классом реализации, не обязательно используемым реализациями поставляемых устройств.) Я в основном использую большие файлы на диске, но я действительно хочу полиморфизмтак что я могу легко заменить альтернативные реализации (например, использовать stringstream вместо fstream для модульных тестов) без всей сложности и сопряжения во время компиляции глубокого создания шаблона.

Есть ли у кого-нибудь какие-либо рекомендации стандартаподход к этому?Это похоже на обычную ситуацию, поэтому я не хочу изобрести свои собственные интерфейсы без необходимости.Например, что-то вроде java.nio.FileChannel кажется идеальным.

Мое лучшее решение на данный момент - это положить тонкий полиморфный слой поверх устройств Boost.Iostreams.Например:

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

Ответы [ 2 ]

1 голос
/ 16 июня 2010

Вы смотрели класс и подклассы Qt QIODevice? Я не совсем уверен, подходит ли он вам, но, возможно, стоит попробовать: QIODevice .

0 голосов
/ 13 июля 2010

Я только что получил набор абстрактных интерфейсов, аналогичных тому, что я обрисовал в этом вопросеКажется, для этого не существует легких, полиморфных стандартов ...

...