针对C++多态,可搜索,二进制I/O接口的建议

Tre*_*son 5 c++ polymorphism file-io iostream boost-iostreams

我一直在使用std::istreamostream作为C++中随机访问二进制I/O的多态接口,但它在许多方面似乎不是最理想的:

  • 由于streampos/streamoff限制,64位寻道是不可移植的并且容易出错; 目前使用boost/iostreams/positioning.hpp作为解决方法,但需要警惕
  • 缺少截断或扩展文件等操作(ala POSIX ftruncate)
  • 具体实施之间的不一致; 例如,stringstream有独立的获取/放置位置,而filestream没有
  • 平台实施之间的不一致; 例如,寻求通过文件结束或使用failbit/ badbit出错的行为
  • 不需要所有的格式化设施,stream甚至可能需要缓冲streambuf
  • streambuf错误报告(即异常与返回错误指示符)在实践中被认为是依赖于实现的

我喜欢Boost.Iostreams Device概念提供的简化界面,但它是作为函数模板而不是多态类提供的.(有一个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;
};
Run Code Online (Sandbox Code Playgroud)

Tre*_*son 0

我最终得到了一组类似于我在问题中概述的抽象接口。似乎没有任何轻量级的、多态的标准......