我一直在使用Boost序列化库,这实际上非常好,并且让我使用简单的包装器将可序列化对象保存到字符串中,如下所示:
namespace bar = boost::archive;
namespace bio = boost::iostreams;
template <class T> inline std::string saveString(const T & o) {
std::ostringstream oss;
bar::binary_oarchive oa(oss);
oa << o;
return oss.str();
}
template <class T> inline void saveFile(const T & o, const char* fname) {
std::ofstream ofs(fname, std::ios::out|std::ios::binary|std::ios::trunc);
bar::binary_oarchive oa(ofs);
oa << o;
}
template <class T> inline void loadFile(T & o, const char* fname) {
std::ifstream ifs(fname, std::ios::in|std::ios::binary);
assert(ifs.good()); // XXX catch if file not found
bar::binary_iarchive ia(ifs);
ia >> o;
} …
Run Code Online (Sandbox Code Playgroud) 如何构建boost
的iostreams
库gzip
和bzip2
支持?
我的项目是使用旧版本的Boost的iostreams w/bzip2.我现在正在尝试升级到Boost 1.51.起初我没有用bzip编译,所以很明显我让链接器大喊大叫libboost_bzip2-vc100-mt-sgd-1_51.lib丢失了.然后我按照这些说明(并添加了静态标志)来编译该文件.
但是,运行链接器现在会返回一堆缺少的符号:
>error LNK2001: unresolved external symbol "protected: __thiscall boost::iostreams::detail::bzip2_base::~bzip2_base(void)" (??1bzip2_base@detail@iostreams@boost@@IAE@XZ)
>error LNK2001: unresolved external symbol "protected: __thiscall boost::iostreams::detail::bzip2_base::bzip2_base(struct boost::iostreams::bzip2_params const &)" (??0bzip2_base@detail@iostreams@boost@@IAE@ABUbzip2_params@23@@Z)
>error LNK2001: unresolved external symbol "int const boost::iostreams::bzip2::stream_end" (?stream_end@bzip2@iostreams@boost@@3HB)
...
Run Code Online (Sandbox Code Playgroud)
任何想法如何来lib不包含所有这些代码?我错过了什么?我在Windows上使用VS2010.
编辑:知道了!
有一个没有bzip编译的旧版libboost_iostreams-vc100-mt-sgd-1_51.lib.我仍然不确定的是:我使用的原始编译:
>b2 --with-iostreams -sBZIP2_SOURCE=D:\Work\external\bzip2-1.0.6 -sZLIB_SOURCE=d:\work\external\zlib-1.2.3 runtime-link=static
Run Code Online (Sandbox Code Playgroud)
这产生了以下文件:
libboost_bzip2-vc100-mt-s-1_51.lib
libboost_bzip2-vc100-mt-sgd-1_51.lib
Run Code Online (Sandbox Code Playgroud)
对于"正确的"编译(解决了问题),我使用了:
>b2 --with-iostreams -sBZIP2_SOURCE=D:\Work\external\bzip2-1.0.6 runtime-link=static
Run Code Online (Sandbox Code Playgroud)
即只是删除了zlib,因为它对我来说是不必要的.它产生了:
libboost_bzip2-vc100-mt-s-1_51.lib
libboost_bzip2-vc100-mt-sgd-1_51.lib
libboost_iostreams-vc100-mt-s-1_51.lib
libboost_iostreams-vc100-mt-sgd-1_51.lib
Run Code Online (Sandbox Code Playgroud)
为什么没有在原始编译中生成iostreams库?很奇怪.
谢谢.
我使用Boost.Serialization来序列化std :: map.代码看起来像这样
void Dictionary::serialize(std::string & buffer)
{
try {
std::stringstream ss;
boost::archive::binary_oarchive archive(ss);
archive << dict_;
buffer = ss.str();
} catch (const std::exception & ex) {
throw DictionaryException(ex.what());
}
}
void Dictionary::deserialize(const char * const data, int length)
{
try {
namespace io = boost::iostreams;
io::array_source source(data, length);
io::stream<io::array_source> in(source);
boost::archive::binary_iarchive archive(in);
archive >> dict_;
} catch (const std::exception & ex) {
throw DictionaryException(ex.what());
}
}
Run Code Online (Sandbox Code Playgroud)
我在Mac Snow Leopard和Ubuntu Lucid 10.04上编译并测试了代码.两个系统都有Boost 1.40.在Mac上我自己构建了代码.在Ubuntu框中,我通过aptitude获得了二进制文件.
问题:当我在Mac上序列化地图时,我无法在Ubuntu框中反序列化它.如果我尝试,我会收到无效的签名异常.
Boost C++库具有Function Template tee
类模板tee_filter和tee_device提供了两种分割输出序列的方法,以便将所有数据同时定向到两个不同的位置.
我正在寻找一个完整的C++示例,使用Boost tee输出到标准输出和像"sample.txt"这样的文件.
我想在内存中创建一个映射的二进制文件; 但是我不确定如何创建要映射到系统的文件.我多次阅读文档并意识到有2个映射文件实现,一个在iostream中,另一个在进程间.
你们对如何在共享内存中创建映射文件有任何想法吗?我试图允许多线程程序读取以二进制文件格式写入的大型double数组.iostream中的映射文件和进程间的区别是什么?
在Boost.Process 0.5(http://www.highscore.de/boost/process0.5/index.html)的这个简单示例中,程序(ls
)的输出正在输入流.流工作正常但与预期相反,流程在程序完成后不会变为无效(例如,流末尾)(类似于之前版本的Boost.Process,例如http://www.highscore.de/boost /process/index.html)
is
在子程序退出后,为了使流(在示例中)自动无效,我缺少什么?
也许我必须在Boost.Streams stream
中设置一个选项file_descriptor
?
#include <boost/process.hpp> // version 0.5 from http://www.highscore.de/boost/process0.5/process.zip
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
using namespace boost::process;
using namespace boost::process::initializers;
using namespace boost::iostreams;
int main(){
boost::process::pipe p = create_pipe();
file_descriptor_sink sink(p.sink, close_handle);
child c = execute(run_exe("/usr/bin/ls"), bind_stdout(sink));
file_descriptor_source source(p.source, close_handle);
stream<file_descriptor_source> is(source);
std::string s;
while(std::getline(is, s)){
std::cout << "read: " << s << std::endl;
}
std::clog << "end" << std::endl; // never reach
}
Run Code Online (Sandbox Code Playgroud) 我实现了文件的gzip/zlib解压缩,如增强网站上的示例所示.
void CompressionUtils::Inflate(std::ifstream& inputFile,
std::ofstream& outputFile)
{
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::gzip_decompressor());
in.push(inputFile);
boost::iostreams::copy(in, outputFile);
}
Run Code Online (Sandbox Code Playgroud)
这很好用.我也是从一个套接字读取数据,我从一个基于休息的JSON服务获得了这个数据.我想我会写一个基于内存的实现,这有多难.好吧,我发现我不理解流和流缓冲区.我责怪过去几年在Java;)..所以我开始走这条道路.
void CompressionUtils::Inflate(char* compressed,
int size,
char* decompressed)
{
boost::iostreams::stream<boost::iostreams::array_source> source(compressed,size);
//std::stringstream str;
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::gzip_decompressor());
in.push(source);
//boost::iostreams::copy(in, str);
}
Run Code Online (Sandbox Code Playgroud)
但我不知道我可以使用哪种流来基本上获得解char*
压缩流的解压缩表示.这应该很容易,而且很可能是,但是我在过去的几个小时里一直在浪费不成功的尝试.
我写了一个Logparser应用程序,现在我想实现.gz文件的解压缩.我尝试使用boost :: iostreams和zlib这似乎有效,但我不知道如何处理从压缩文件中获得的输入.
这是我做的:
input.open(p.source_at(i).c_str(), ios_base::in | ios_base::binary);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::gzip_decompressor());
in.push(input);
boost::iostreams::copy(in, cout);
Run Code Online (Sandbox Code Playgroud)
如果我的源文件的.gz结尾,则运行此代码.最后一行将解压缩的文件流正确输出到cout.
但是如何从解压缩文件中逐行获取?我的程序使用getline(输入,传输)来读取输入流中的行(如果它没有被压缩).
现在我想以相同的方式从解压缩文件中读取,但是如何从中获取新行?
这个加速计算对我没什么帮助.
提前致谢!
关于SO的第一个问题!:d
我给了一个std::istream
包含UTF-16编码字符串的字符串.想象一下这样打开的UTF-16编码文本文件:
std::ifstream file( "mytext_utf16.txt", std::ios::binary );
Run Code Online (Sandbox Code Playgroud)
我想将此流传递给一个带std::wistream&
参数的函数.我无法将文件流类型更改为std :: wifstream.
问题:标准或boost库中是否有任何工具可以让我"重新解释"istream作为一个wistream?
我想象一个类似于std :: wbuffer_convert的适配器类,除了它不应该进行任何编码转换.基本上对于从适配器类读取的每个wchar_t,它应该只从关联的istream中读取两个字节,并将reinterpret_cast
它们读取到wchar_t.
我已经创建了一个使用boost :: iostreams的实现,可以像这样使用,就像一个魅力:
std::ifstream file( "mytext_utf16.txt", std::ios::binary );
// Create an instance of my adapter class.
reinterpret_as_wide_stream< std::ifstream > wfile( &file );
// Read a wstring from file, using the adapter.
std::wstring str;
std::get_line( wfile, str );
Run Code Online (Sandbox Code Playgroud)
那我为什么要问?因为我喜欢重用现有代码而不是重新发明轮子.
boost-iostreams ×10
c++ ×9
boost ×8
bzip2 ×2
iostream ×2
zlib ×2
gzip ×1
interprocess ×1
process ×1