【问题标题】:Cast a variable of filtering_istream type to ifstream type?将filtering_istream类型的变量转换为ifstream类型?
【发布时间】:2017-09-20 12:21:52
【问题描述】:

我在使用“boost/iostreams/filtering_stream.hpp”时使用 filetering_istream 类型将信息保存在解压缩文件中。但我想将其转换为 ifstream 类型。它有什么办法吗?非常感谢!

代码如下:

#include <istream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp>

int main(){    
    std::ifstream file("test_data.dat.gz");

    boost::iostreams::filtering_istream in;

    in.push(boost::iostreams::gzip_decompressor());

    in.push(file);

    /* add code to convert filtering_istream 'in' into ifstream 'pfile' */

    /* It seems that the following code returns a pointer NULL */

    // std::ifstream* pfile = in.component<std::ifstream>(1); 

    return 0;

}

在尝试了 zett42 提出的 boost::ref 和 boost::wrapper 之后,ifstream 确实有效。唯一的问题是它没有给出想要的短语。

在我的 .gz 文件中,我写道:

THIS IS A DATA FILE!
8 plus 8 is 16

但是使用 ifstream,我得到了:

is_open: 1

\213&lt;\373Xtest_data.dat\361\360V"G\307G7OWE.\205\202\234\322b\205\314bC3.\327+&gt;\314$

我不确定这里发生了什么,我可以做些什么来恢复它吗?

【问题讨论】:

  • 如果您使用ifstream,您将读取压缩数据。也许我完全误解了你的问题。如果要读取未压缩的数据,只需从in 读取。那么就不需要“投射”任何东西了。

标签: c++ boost casting iostream ifstream


【解决方案1】:

来自filtering_stream的参考:

filtering_stream 派生自 std::basic_istream、std::basic_ostream 或 std::basic_iostream,取决于其 Mode 参数。

所以不,您不能将filtering_stream 直接转换为ifstream,因为两者之间没有继承关系。

您可以做什么,如果您的过滤器链以ifstream 的设备结束,您可以通过调用filtering_stream::component() 来获取该设备。对于流,此函数返回boost::iostreams::detail::mode_adapter(您可以通过调用in.component_type(1) 查看类型)。

依赖可能会随着下一个 boost 版本而改变的内部 boost 类型(由命名空间“detail”表示)可能不是一个好主意,因此一种解决方法是改用 boost::reference_wrapper

#include <iostream>
#include <istream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/core/ref.hpp>

int main(){    
    std::ifstream file("test_data.dat.gz");

    boost::iostreams::filtering_istream in;

    in.push(boost::iostreams::gzip_decompressor());

    in.push(boost::ref(file));

    if( auto pfile = in.component<boost::reference_wrapper<std::ifstream>>( 1 ) )
    {
        std::ifstream& rfile = *pfile;
        std::cout << "is_open: " << rfile.is_open() << "\n";
    }
}

【讨论】:

  • 感谢这个灵感,但似乎pfile是一个NULL指针,如果我想打印里面的内容会导致分段错误。你对此有什么想法吗?我确信“in”是正确的,因为我可以使用 getline 函数输出里面的内容。太好了!
  • @hyoukai 你能在你的问题中添加一个代码示例吗?
  • 感谢您的关注。已添加代码。如果你能给我一些想法,那就太好了!
  • 否则,我想知道是否可以将istream转换为ifstream?谢谢
  • @hyoukai 我对component() 方法有一个误解,该方法现已修复。查看更新的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2020-02-01
  • 2021-10-25
  • 1970-01-01
  • 2020-06-19
  • 2011-09-13
  • 2020-10-25
相关资源
最近更新 更多