【问题标题】:Possible to create a dual-seekable Boost Iostream using a file_descriptor?可以使用 file_descriptor 创建可双向搜索的 Boost Iostream 吗?
【发布时间】:2011-01-24 12:47:17
【问题描述】:

我正在尝试使用 std::iostream 接口更新随机访问二进制文件,并通过 seekg/seekp 管理单独的 get/put 位置。 stringstream 一切正常,但是当我使用 Boost.Iostream(特别是 boost::iostreams::stream<:iostreams:: href="http://www.boost.org/doc/libs/1_41_0/libs/iostreams/doc/classes/file_descriptor.html#file_descriptor" rel="nofollow" target="_blank">file_descriptor>)创建基于文件描述符的流时,get/put 位置是不再独立。

我从Modes 上的文档中收集到,我正在寻找的是“双重可搜索”流。文档显示 Mode 是 stream 的模板参数,“主要供内部使用”,但这似乎(不再?)正确。相反,模式(又名类别?)直接取自设备:

template< typename Device,
          typename Tr = ...,
          typename Alloc = ...>
struct stream : detail::stream_base<Device, Tr, Alloc> {
public:
    typedef typename char_type_of<Device>::type  char_type;
    struct category 
        : mode_of<Device>::type,
          closable_tag,
          detail::stream_traits<Device, Tr>::stream_tag
        { };

主要问题:是否有某种方法可以从设备(例如 file_descriptor(标记为可搜索但不是双搜索))获得双重搜索行为?

次要问题:对于 seekg/seekp 的独立性是否有任何一般性保证?我从网络搜索中收集到 stringstream 似乎是独立的,但 fstream 可能不是。但是,我找不到任何权威的东西。

【问题讨论】:

    标签: c++ boost iostream


    【解决方案1】:

    如果您构造一个双向搜索boost::iostreams::device,它将支持两个单独的获取/放置位置,可以借助iostreams::seek 函数进行修改。

    大致如下:

    struct binary_seekable_device 
     : boost::iostreams::device<boost::iostreams::bidirectional_seekable>
    {
        explicit binary_seekable_device(int fd)
          : fd(fd), pos_read(0), pos_write(0) {}
    
        std::streamsize read(char *s, std::streamsize n);
        std::streamsize write(char const *s, std::streamsize n);
        std::streampos seek(boost::iostreams::stream_offset off,
            std::ios::seekdir way, std::ios::openmode which);
    
        int fd; 
        std::size_t pos_read;
        std::size_t pos_write;
    };
    

    您需要通过填写三个函数(读取、写入、查找)来实现您的流逻辑,详情请参阅示例和文档。对您来说重要的一点是参数std::ios::openmode which 为您提供了您需要更新哪些位置(读取、写入或两者)的线索。

    现在您在实例化 boost::iostreams::stream: 时使用此设备:

    int fd = open(...);
    boost::iostream::stream<binary_seekable_device> s(fd);
    

    其中 s 是您的流实例,您可以使用它来执行所需文件操作。

    【讨论】:

    • 根据您的回答和对 Boost.Iostream 代码的进一步阅读,听起来我需要推出自己的 boost::iostreams::file_descriptor 版本。一方面,只有 3 种方法可以实现;另一方面,我需要为 Windows/POSIX 可移植性复制所有“#ifdef BOOST_IOSTREAMS_WINDOWS”内容。 (这些流用于访问使用特定于操作系统的 API 创建的临时文件。)无论如何,感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2015-07-22
    • 2013-06-18
    • 1970-01-01
    • 2023-01-20
    相关资源
    最近更新 更多