c++ boost库流处理

前言

c++原生的流处理并不支持流的压缩处理,因此需要使用boost库的流处理。

boost流处理

即boost.iostreams库,我需要用到的组成部分如下:

  • device(设备) - 流的起点source(源设备),流的终点sink(目标设备)
  • filter(过滤器) - 读取数据时的输入过滤器,写入数据时的输出过滤器
  • stream(流) - 用来连接设备和过滤器,实现类似标准流的功能

前置编译

iostreams库是一个由头文件组成的库,位于<boost/iostreams/>下,分为无需编译的功能和需要编译才能使用的功能。
而需要用到的压缩功能则要进行其他库的额外安装,这里就用bzip2举例。

sudo apt-get install libbz2-dev

使用该命令安装bzip2的库,就可以在boost的流处理中使用bzip2格式的压缩了。

惯例用法

// 基本流处理所需的头文件
#include <boost/iostreams/stream.hpp>
// array设备所需的头文件
#include <boost/iostreams/device/array.hpp>
// 过滤流头文件
#include <boost/iostreams/filtering_stream.hpp>

// 命名空间起别名,方便使用
namespace io = boost::iostreams;
// 使用命名空间
using namespace io;

设备

设备最基本的特征是能够处理“字符类型”。

设备模式

  • 输入模式(input)
  • 输出模式(output)
  • 双向模式(bidirectional) 既可以输入,也可以输出
  • 可定位模式(seekable) 可重定位操作的位置
  • 可定位输入模式(input-seekable)
  • 可定位输出模式(output-seekable)

我需要使用的就是可定位输入模式和可定位输出模式。

设备类型

字符类型和访问模式是设备最重要的两个特征,除此以外,设备的类型(原设备、接收设备、过滤器)也可作为分类的依据。特征的标签位于<boost/iostreams/categories.hpp>中。
判断一个类是否为设备可以使用原函数is_device<T>

自定义设备

可以根据<boost/iostreams/concepts.hpp>中定义的设备的子概念来进行扩展。
比如source和sink两个类。

预定义设备

这里就简单列举一下,因为使用不到,就不详细了解了。

  • 数组设备
标准容器设备

boost.range库中提供的函数boost::make_iterator_range()可以把容器传递给过滤流从而创建出可以用于输入的流。

文件设备

是我需要使用的,也是要学习的重点。
位于<boost/iostreams/device/file.hpp>中,基于标准库的文件流提供了对文件的访问。
分为以下三类:

  • file_source 源设备
  • file_sink 目标设备
  • file 可定位设备

过滤器

由于其他过滤器暂时不适用,这里只介绍一下压缩过滤器的用法。
bzip2的头文件位于<boost/iostreams/filter/bzip2.hpp>中,使用方法很简单:

string str("test");
string zip_str,unzip_str;

// 定义输出流,
filtering_ostream fout(
	bzip2_compressor() | io::back_inserter(zip_str));
	
io::copy(
	boost::make_iterator_range(str)
	,zout);

filtering_ostream unzip_out(
	bzip2_decompressor() | io::back_inserter(unzip_str));

io::copy(
	boost::make_iterator_range(zip_str),
	unzip_out);

std::cout<<upzip_str<<std::endl;	

分为基本流和过滤流,基本流一般使用stream,过滤流是基本流的强化版,可以在连接设备的基础上连接过滤器和链,过滤流一般使用filtering_stream。

流处理函数

最为重要的是io::copy(),其位于头文件<boost/iostreams/copy.hpp>中。
其声明:

template<typename Source,typename Sink>
std::streamsize copy(Source &src,Sink &sink);

常用的函数<boost/iostreams/operations.hpp>

  • get(d) 从源设备或流中获取一个字符
  • read(d,s,n) 从源设备或流中获取多个字符
  • put(d,c) 向接收设备或流中写入一个字符
  • write(d,s,n) 向接收设备或流中写入多个字符
  • seek(d,off,way) 随机访问设备或流
  • flush(d) 刷新设备或整个流,清空缓冲区
  • close(d) 关闭设备或流

参数说明:d是device的缩写,指设备,s为size的缩写,指大小,off为offset的缩写,指偏移量,c为char的缩写,指字符,way指访问方式。

hello world

#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>                
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/operations.hpp>
#include <bzlib.h>

namespace io = boost::iostreams;
using namespace io;
using namespace std;

int main()
{
    // 创建输出文件设备
    file_sink fsink("test.txt");
    // 创建过滤流 添加压缩、目标设备
    filtering_ostream out(
        bzip2_compressor() | fsink
    );
    char buf[] = "test 1 2 3 4";
    io::write(out,buf,sizeof(buf));
    // 输出一些格式数据
    io::close(out);
    // 创建读入文件设备
    file_source fsource("test.txt");
    filtering_istream in;
    in.push(bzip2_decompressor());
    in.push(fsource);
    char a[64];
    io::read(in,a,64);
    printf("%s\n",a);
    fsource.close();
    
}

CMakeLists.txt文件

cmake_minimum_required(VERSION 3.0.2)
set(CMAKE_CXX_STANDARD 14)
project(Test)

add_definitions(-std=c++11)
add_definitions(-g -o3)

find_package(Boost REQUIRED COMPONENTS filesystem iostreams)
find_package(BZip2 REQUIRED)

include_directories(${Boost_INCLUDE_DIR})
include_directories(${BZIP2_INCLUDE_DIR})

link_directories(${Boost_LIBRARY_DIRS})
link_directories(${BZIP2_LIBRARY_DIRS})
add_definitions(${BZIP2_DEFINITIONS})

set(SRC
    src/test.cpp
)


add_executable(zip_test ${SRC})

target_link_libraries(zip_test  -lm -lstdc++ ${BZIP2_LIBRARIES} ${Boost_LIBRARIES})

在这里插入图片描述
可以看到,这一demo成功完成了压缩解压缩的过程。

参考文献

《C++11/14高级编程:Boost程序库探秘(第3版)》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值