利用QBuffer和QLinkedList做数据块存储队列
Qt中QByteArray存储数据很方便,使用QBuffer存储大块数据更方便。QBuffer类包装了QByteArray类对象,实际存储还是使用了QByteArray,但QBuffer实现了QIODevice接口,其拥有丰富的读写接口,使操作更方便。
主要需求是,存进去的数据接口函数参数要求是char* dat 和int datalength是形式,取出来的数据接口函数参数也是一样。
qt里对基本数据格式都进行了封装,提供了如QChar、QBitArray、QByteArray类,使用起来也是很方便。如网络上接受到数据,都是帧流,处理数据时,需要按字节处理(因为通信协议多按字节定义),如上的缓存接口定义就比较合适。
使用QBuffer+QLinkedList做一个缓存队列就非常容易了。
下面给出代码:
FrameStreamManager.cpp
- #include "FrameStreamManager.h"
- FrameStreamManager::FrameStreamManager()
- {
- }
- FrameStreamManager::~FrameStreamManager()
- {
- }
- int FrameStreamManager::putFrame(char *in,int length)
- {
- int ret;
- QMutexLocker locker(&mutex);
- QBuffer *qbuf = new QBuffer();
- qbuf->open(QBuffer::ReadWrite);
- ret = qbuf->write(in,length);
- qbuf->close();
- list.append(qbuf);
- return ret;
- }
- int FrameStreamManager::getFrame(char *retbuf,int size)
- {
- QMutexLocker locker(&mutex);
- QBuffer *qbuf;
- int ret=;
- if(list.size() > )
- {
- qbuf = list.takeFirst();
- qbuf->open(QBuffer::ReadWrite);
- ret = qbuf->read(retbuf,size);
- qbuf->close();
- delete qbuf;
- }
- return ret;
- }
- int FrameStreamManager::getFrameSize()
- {
- return list.size();
- }
FrameStreamManager.h
- #ifndef FRAMESTREAMMANAGER_H
- #define FRAMESTREAMMANAGER_H
- #include <QLinkedList>
- #include <QBuffer>
- #include <QByteArray>
- #include <QMutexLocker>
- #include <QMutex>
- class FrameStreamManager
- {
- public:
- FrameStreamManager();
- ~FrameStreamManager();
- private:
- QLinkedList<QBuffer*> list;
- QMutex mutex;
- public:
- int putFrame(char *in,int length);
- int getFrame(char *rebuf,int size);
- int getFrameSize(void);
- };
- #endif
测试文件:
mainwindow.cpp
- #include "mainwindow.h"
- #include <QLabel>
- #include <QtDebug>
- #include <QBuffer>
- #include <QPushButton>
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- {
- this->setFixedSize(,);
- QLabel *label = new QLabel("hello you are",this);
- label->move(,);
- QPushButton *btn1 = new QPushButton("put",this);
- connect(btn1, SIGNAL(clicked()), this, SLOT(btn1Clicked()));
- btn1->move(,);
- QPushButton *btn2 = new QPushButton("show",this);
- connect(btn2,SIGNAL(clicked()),this,SLOT(btn2Clicked()));
- btn2->move(,);
- QPushButton *btn3 = new QPushButton("get",this);
- connect(btn3,SIGNAL(clicked()),this,SLOT(btn3Clicked()));
- btn3->move(,);
- for(int i=;i<;i++)
- defaultbuf[i] = ;
- memset(retbuf,,);
- /*// int BUFSIZE = 2048;
- // QBuffer qbuf;
- // qbuf.open(QBuffer::ReadWrite);
- // char *buf = (char*)malloc(BUFSIZE);
- // for(int i=0;i<BUFSIZE;i++)
- // {
- // buf[i] = 234;
- // }
- // int ret = qbuf.write(buf,BUFSIZE);
- // qbuf.close();
- // qDebug()<<"ret = "<<ret;
- // char *retbuf = (char *)malloc(BUFSIZE);
- // memset(retbuf,0,BUFSIZE);
- // qbuf.open(QBuffer::ReadWrite);
- // ret = qbuf.read(retbuf,BUFSIZE);
- // qDebug()<<"ret = "<<ret;
- // for(int i=0;i<BUFSIZE;i++)
- // {
- // if(retbuf[i] != (char)234)
- // {
- // qDebug()<<"Error at "<<i<<" : "<<retbuf[i];
- // }
- // }
- // qbuf.close();
- // free(buf);
- // free(retbuf); */
- }
- MainWindow::~MainWindow()
- {
- }
- void MainWindow::btn1Clicked()
- {
- qDebug()<<"\nput frame!";
- int len = fsm.putFrame(defaultbuf,);
- if(len != )
- qDebug()<<"put frame buf";
- }
- void MainWindow::btn2Clicked()
- {
- qDebug()<<"\nshow frame list size!";
- int len = fsm.getFrameSize();
- qDebug()<<"Now Frame Size = "<<len;
- }
- void MainWindow::btn3Clicked()
- {
- qDebug()<<"\nget frame and check!";
- int len = fsm.getFrame(retbuf,);
- if(len != )
- qDebug()<<"get frame returns "<<len;
- else
- {
- for(int i=;i<;i++)
- {
- if(retbuf[i] != )
- qDebug()<<" get data error at "<<i<<" : "<<retbuf[i];
- }
- }
- memset(retbuf,,);
- }
mainwindow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include "FrameStreamManager.h"
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- MainWindow(QWidget *parent = );
- ~MainWindow();
- private slots:
- void btn1Clicked();
- void btn2Clicked();
- void btn3Clicked();
- private:
- FrameStreamManager fsm;
- char defaultbuf[];
- char retbuf[];
- };
- #endif // MAINWINDOW_H
QByteArray也是可以完成同样功能,QByteArray有如下函数,QByteArray & QByteArray::append(const char *str,int len) 和char * QByteArray::data()。就是QByteArray会在返回的char* 数据后自动加‘\0’,但int QByteArray::size()返回来的数是不含'\0',利用size()函数和data()封装一下就可以达到上面QBuffer达到的效果。
而且使用QByteArray有个好处,QByteArray重载了操作符=,所以FrameStreamManager里的list可以这样定义-->QLinkedList<QByteArray> list。从队列中取数据时可以直接写QByteArray tmp = list.takeFirst();而QBuffer没有重载=操作符,QBuffer tmp = list.takeFirst();这样就写就会直接报错。定义队列时就必须改成上面那样,就需要自己管理内存了。同时,使用QBuffer还需要打开和关闭设备。
综上,队列中使用QByteArray做存储,封装使用更方便。
利用QBuffer和QLinkedList做数据块存储队列的更多相关文章
- HDFS中数据节点数据块存储示例
数据块在数据节点上是按照如下方式存储的. 首先是一个存储的根目录/Hadoop/data/dfs/dn,如下图所示: 接着进入current目录,如下图所示: 再进入后续的BP-433072574-1 ...
- [转]Oracle数据块体系的详细介绍
数据块概述Oracle对数据库数据文件(datafile)中的存储空间进行管理的单位是数据块(data block).数据块是数据库中最小的(逻辑)数据单位.与数据块对应的,所有数据在操作系统级的最小 ...
- Ext2文件系统布局,文件数据块寻址,VFS虚拟文件系统
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
前言 我们知道HDFS集群中,所有的文件都是存放在DN的数据块中的.那我们该怎么去查看数据块的相关属性的呢?这就是我今天分享的内容了 一.HDFS中数据块概述 1.1.HDFS集群中数据块存放位置 我 ...
- HDFS源码分析数据块校验之DataBlockScanner
DataBlockScanner是运行在数据节点DataNode上的一个后台线程.它为所有的块池管理块扫描.针对每个块池,一个BlockPoolSliceScanner对象将会被创建,其运行在一个单独 ...
- mongodb 数据块的迁移流程介绍
1. 基本概念 1.1 Chunk(数据块) 表示特定服务器上面,连续范围的分片键值所包含的一组数据,是一个逻辑概念. 例如,某数据块记录如下: { "_id" : "c ...
- vuex数据持久化存储
想想好还是说下vuex数据的持久化存储吧.依稀还记得在做第一个vue项目时,由于刚刚使用vue,对vue的一些基本概念只是有一个简单的了解.当涉及到非父子组件之间通信时,选择了vuex.只是后来竟然发 ...
- 利用php的序列化和反序列化来做简单的数据本地存储
利用php的序列化和反序列化来做简单的数据本地存储 如下程序可以做为一个工具类 /** * 利用php的序列化和反序列化来做简单的数据本地存储 */ class objectdb { private ...
- 【oracle11g,17】存储结构: 段的类型,数据块(行连接、行迁移,块头),段的管理方式,高水位线
一.段的类型: 1.什么是段:段是存储单元. 1.段的类型有: 表 分区表 簇表 索引 索引组织表(IOT表) 分区索引 暂时段 undo段 lob段(blob ,clob) 内嵌表(record类型 ...
随机推荐
- 【Luogu】P3116会议时间(拓扑排序,DP)
题目链接 本题使用拓扑排序来规划DP顺序.设s[i][j]表示i步是否能走到j这个点,e[i][j]表示i步是否能走到j这个点——用第二条路径.因为要满足无后效性和正确性,只有第i个点已经全部更新完毕 ...
- [COI2007] Patrik 音乐会的等待 (单调栈,模拟)
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
- 请问 内网的 dns服务器 为什么和 外网的dns服务器 一样??
公司内的内网使用192.169.X.X的内网地址,但是在DNS段填写的是210.34.X.X,显然这是一个公网固定IP,我不明白的是:为什么内部网客户端使用的DNS服务器是公网上的IP呢?内网客户端能 ...
- 使用vue-cli创建项目(包含npm和cnpm的安装nodejs的安装)
转:http://www.cnblogs.com/wisewrong/p/6255817.html vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue ...
- Modular Production Line
Modular Production Line 时空限制: 1000ms /65536K An automobile factory has a car production line. Now ...
- lnux 下 core文件
1. core文件的简单介绍在一个程序崩溃时,它一般会在指定目录下生成一个core文件.core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的. 2. 开启或关闭core文件的生成用以下 ...
- Redis命令行之List
一.Redis之List简介 1. List是简单的字符串列表,按照插入顺序排列. 2. 一个列表最多可存储232-1个元素(40多亿). 二.Redis之List命令行操作 Lrange:获取列表指 ...
- 实验十二 swing图形界面设计
1.源程序 package information;import java.awt.Container;import java.awt.FlowLayout;import java.awt.event ...
- Java代码规范和质量检查插件-Checkstyle(官方资源)
其实Checkstyle是一个JAR包,然后第三方开发者开发了Eclipse/IDEA的插件. 官网: https://github.com/checkstyle/checkstyle Eclipse ...
- 使用Maven运行Java main的方法(转)
使用Maven运行Java Main的方法(既Java Application项目),可以有如下方式解决: 1.将Maven项目导入到eclipse中,然后直接项目右键[Run As]->[Ja ...