将Boost filtering_streambuf中的文件解压缩为std :: vector< char&gt ;? [英] Decompress file from Boost filtering_streambuf to std::vector<char>?

查看:240
本文介绍了将Boost filtering_streambuf中的文件解压缩为std :: vector< char&gt ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解压缩一个使用DEFLATE算法压缩的文件,并将其放入向量< unsigned char> 。从我到目前为止的研究,看起来我可以使用 boost :: iostreams :: filtering_streambuf ,然后使用 boost :: iostreams :: copy()将其转换为 boost :: interprocess :: basic_vectorstream< std :: vector< unsigned char>> 将底层向量从向量流中拉出。但是,我收到了大量的编译器错误,从这开始:

  / usr / include / boost / iostreams / copy .hpp:在函数'std :: streamsize boost :: iostreams :: detail :: copy_impl(Source,Sink,std :: streamsize)[with Source = boost :: reference_wrapper< boost :: iostreams :: filtering_streambuf& boost :: iostreams :: input> >,Sink = boost :: reference_wrapper< boost :: interprocess :: basic_vectorstream< std :: vector< unsigned char> > >,std :: streamsize = long int]':
/usr/include/boost/iostreams/copy.hpp:245:79:从std :: streamsize实例化boost :: iostreams :: copy(Source& ;,Sink& std :: streamsize,typename boost :: enable_if< boost :: iostreams :: is_std_io< Source>> :: type *,typename boost :: enable_if< boost :: iostreams :: is_std_io< Sink> ; :: type *)[with Source = boost :: iostreams :: filtering_streambuf< boost :: iostreams :: input>,Sink = boost :: interprocess :: basic_vectorstream< std :: vector< unsigned char> >,std :: streamsize = long int,typename boost :: enable_if< boost :: iostreams :: is_std_io< Source> > :: type = void,typename boost :: enable_if< boost :: iostreams :: is_std_io< Sink> > :: type = void]'
ValueFileReader.cpp:92:41:从这里实例化
/usr/include/boost/iostreams/copy.hpp:178:5:error:static assertion failed :(is_same< src_char,snk_char> :: value)

下面(缩短并在这里使用命名空间):

  using namespace boost :: iostreams 
using namespace boost :: interprocess;

filtering_streambuf< input>在;
std :: ifstream file(filename,std :: ifstream :: in);
in.push(zlib_decompressor());
in.push(file);

basic_vectorstream< std :: vector< unsigned char>> vectorStream;
copy(in,vectorStream);
std :: vector< unsigned char> chars(vectorStream.vector());

我看过,但我不知道如果将一切都复制到一个向量,然后从向量解压缩将是一个向量,如果可能的解压缩一个向量的泄漏数据与增强是最有效的方式。



有更好的方法我可以去这个,或者我有正确的想法,但在代码中的一些错误? / p>

解决方案

问题是你的 ifstream filtering_streambuf 使用 char 作为其底层字符类型,但您的 basic_vectorstream 使用 unsigned char 作为其值类型。 Boost代码有一个静态断言,要求这些类型是相同的,所以如果你使用两种不可转换的类型,你不会得到一个编译器错误。



<幸运的是,这里的修复很容易–更改:

  basic_vectorstream< std :: vector< unsigned char> vectorStream; 
copy(in,vectorStream);
std :: vector< unsigned char> chars(vectorStream.vector());

到:

 code> basic_vectorstream< std :: vector< char>> vectorStream; 
copy(in,vectorStream);
std :: vector< unsigned char> chars(
vectorStream.vector()。begin(),
vectorStream.vector()。end()
);

这是安全的,因为 char unsigned char 由C ++标准保证具有相同的对象表示(§3.9.1/ 1)。






与您的直接问题无关,但您还需要将 std :: ios :: binary 传递到文件的构造函数,否则由于行结束转换而导致数据损坏。


I'm trying to decompress a file that was compressed using the DEFLATE algorithm and stuff it into a vector<unsigned char>. From the research I've done so far, it seemed like I could use a boost::iostreams::filtering_streambuf and then use boost::iostreams::copy() to get it into a boost::interprocess::basic_vectorstream<std::vector<unsigned char>> and then pull the underlying vector out of the vectorstream. However, I'm getting a ton of compiler errors, starting with this:

/usr/include/boost/iostreams/copy.hpp: In function ‘std::streamsize boost::iostreams::detail::copy_impl(Source, Sink, std::streamsize) [with Source = boost::reference_wrapper<boost::iostreams::filtering_streambuf<boost::iostreams::input> >, Sink = boost::reference_wrapper<boost::interprocess::basic_vectorstream<std::vector<unsigned char> > >, std::streamsize = long int]’:
/usr/include/boost/iostreams/copy.hpp:245:79:   instantiated from ‘std::streamsize boost::iostreams::copy(Source&, Sink&, std::streamsize, typename boost::enable_if<boost::iostreams::is_std_io<Source> >::type*, typename boost::enable_if<boost::iostreams::is_std_io<Sink> >::type*) [with Source = boost::iostreams::filtering_streambuf<boost::iostreams::input>, Sink = boost::interprocess::basic_vectorstream<std::vector<unsigned char> >, std::streamsize = long int, typename boost::enable_if<boost::iostreams::is_std_io<Source> >::type = void, typename boost::enable_if<boost::iostreams::is_std_io<Sink> >::type = void]’
ValueFileReader.cpp:92:41:   instantiated from here
/usr/include/boost/iostreams/copy.hpp:178:5: error: static assertion failed: "(is_same<src_char, snk_char>::value)"

The code I'm using is below (shortened up and doing "using namespace" for brevity here):

using namespace boost::iostreams;
using namespace boost::interprocess;

filtering_streambuf<input> in;
std::ifstream file(filename, std::ifstream::in);
in.push(zlib_decompressor());
in.push(file);

basic_vectorstream<std::vector<unsigned char>> vectorStream;
copy(in, vectorStream);
std::vector<unsigned char> chars(vectorStream.vector());

I've seen this thread, but I wasn't sure if copying everything into a vector, then decompressing from the vector would be the most efficient way of going about it.

Is there a better way I can go about this, or do I have the right idea but some error in the code?

解决方案

The problem is that your ifstream and filtering_streambuf use char as their underlying character type, but your basic_vectorstream uses unsigned char as its value type. The Boost code has a static assertion requiring that these types be the same so that you don't get a spew of compiler errors if you use two different types that are not convertible.

Fortunately, the fix here is easy – change:

basic_vectorstream<std::vector<unsigned char>> vectorStream;
copy(in, vectorStream);
std::vector<unsigned char> chars(vectorStream.vector());

to:

basic_vectorstream<std::vector<char>> vectorStream;
copy(in, vectorStream);
std::vector<unsigned char> chars(
    vectorStream.vector().begin(),
    vectorStream.vector().end()
);

This is safe because char and unsigned char are guaranteed by the C++ standard to have the same object representation (§3.9.1/1).


Unrelated to your direct problem, but you also need to pass std::ios::binary to file's constructor, otherwise you'll have corrupt data due to line-ending conversions.

这篇关于将Boost filtering_streambuf中的文件解压缩为std :: vector&lt; char&gt ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆