【问题标题】:Error boost filtering_ostream when returned from a function从函数返回时错误提升过滤_ostream
【发布时间】:2013-10-04 14:09:08
【问题描述】:

只是一个关于 boost::iostream::filtering_ostream() 的快速问题。

我有一个函数,它(在内部)为 boost::iostream::filtering_ostream 创建一个 shared_ptr,并返回一个指向 std::ostream 的共享指针。

每当我不在函数中使用压缩器时,一切似乎都可以正常工作,但是一旦我添加了压缩器,输出文件就会损坏。如果我在 'getOutputStreamComp' 函数中编写文本,那么一切正常。

下面的示例只是将一些数字写入文件,就像 POC 一样。

#include <iostream>
#include <string>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/shared_ptr.hpp>

boost::shared_ptr<std::ostream> getOutputStream(const std::string& fileName)
{
    boost::shared_ptr<boost::iostreams::filtering_ostream> out(boost::shared_ptr<boost::iostreams::filtering_ostream>(new boost::iostreams::filtering_ostream()));
    out->push(boost::iostreams::file_sink(fileName),std::ofstream::binary);

    return out;
}

boost::shared_ptr<std::ostream> getOutputStreamComp(const std::string& fileName)
{
    boost::shared_ptr<boost::iostreams::filtering_ostream> out(boost::shared_ptr<boost::iostreams::filtering_ostream>(new boost::iostreams::filtering_ostream()));
    out->push(boost::iostreams::gzip_compressor());
    out->push(boost::iostreams::file_sink(fileName),std::ofstream::binary);

    return out;
}

int main(int argc, char** argv)
{
    boost::shared_ptr<std::ostream> outFile     = getOutputStream("test.txt");
    boost::shared_ptr<std::ostream> outFileComp = getOutputStreamComp("testcomp.txt.gz");

    // This file is fine.
    for (size_t i(0); i < 10000; ++i)
    {
        *outFile << "i: " << i << std::endl;
    }

    // This file is corrupt.
    for (size_t i(0); i < 10000; ++i)
    {
        *outFileComp << "i: " << i << std::endl;
    }
}

如果您有任何想法,我们将不胜感激!

谢谢,

戴夫

【问题讨论】:

    标签: c++ boost gzip iostream


    【解决方案1】:

    修正错别字(*outFile*outFileComp)后,我无法重现:使用 g++ 4.8.1/boost-1.53​​ 编译,它运行并生成两个好文件:test.txt 有 10,000 行(文件大小78,890) 和 testcomp.txt.gz (文件大小 22,064) 使用 gunzip 解压成 test.txt 的精确副本。

    也许在您的实际程序中,您尝试在程序结束之前检查文件(或至少在对 shared_ptr 的最后引用消失之前)?压缩过滤流的一个常见问题是,刷新 outFileComp 就像您对 std::endl 所做的那样,目前并不会强制完全写出压缩文件。

    【讨论】:

    • 抱歉错字,getOutputStream 和 getOutputStreamComp 函数完全从我的代码复制,但其余的只是一个例子。下次会多想,少打字。你的猜测可能是对的 - 我将再运行几次,看看我是否能弄清楚发生了什么。如果有帮助,我正在使用 VS2012 Express。感谢您的浏览,非常感谢!
    • 好的,所以我想我明白了 - 将 file_sink 推送到 filtering_ostream 时有一个错字,但它允许代码仍然编译。我写了以下内容:out-&gt;push(boost::iostreams::file_sink(fileName),std::ofstream::binary);,应该是:out-&gt;push(boost::iostreams::file_sink(fileName,std::ofstream::binary)); 这似乎解决了我的 Windows 机器上的问题,并且一切正常。再次感谢您的意见 Cubbi,非常感谢您抽出宝贵的时间!
    • @DaveM 这确实很容易错过!我在一个 linux 机器上进行了测试,其中文本和二进制文件没有区别,所以你的程序当然对我有用。您可能希望将您的结果作为答案发布并接受它,以使其对未来的读者更有用。
    【解决方案2】:

    好的,我在Cubbi 的帮助下找到了问题 - 以下行(出现两次):

    out->push(boost::iostreams::file_sink(fileName),std::ofstream::binary);
    

    应该是:

    out->push(boost::iostreams::file_sink(fileName,std::ofstream::binary));
    

    代码仍在编译,所以我可能在 filter_ostream 的某处设置了一个标志,这可能会导致进一步的问题。

    此修复允许按预期创建文件。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 2014-04-19
      • 1970-01-01
      • 2014-02-19
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 2021-03-05
      相关资源
      最近更新 更多