利用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类型 ...
随机推荐
- BZOJ-1269 文本编辑器
.... 这道题就是Noi原题嘛...虽然更容易写... 题意: 建立一个数据结构,并支持以下操作: Insert 区间插入有序序列:Delete 区间删除:Rotate 区间翻转:Get 单点查询 ...
- [luoguP2051] [AHOI2009]中国象棋(DP)
传送门 注释写明了一切 #include <cstdio> #define N 111 #define p 9999973 #define LL long long int n, m; L ...
- 洛谷P3760 - [TJOI2017]异或和
Portal Description 给出一个\(n(n\leq10^5)\)的序列\(\{a_n\}(\Sigma a_i\leq10^6)\),求该数列所有连续和的异或和. Solution 线段 ...
- 【NOI2012】骑行川藏
获得成就:第一次在信竞做神仙数学题 先放个前言,$OI$ 出大型数学题还是比较麻烦的,因为主要是考你数学推导 / 手算式子,你算出来之后把公式套个板子,就得到结论——$OI$ 的大型数学题的代码都是板 ...
- 维修队列(bzoj 1500)
Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...
- [转发]Android 系统稳定性 - ANR(二)
文章都为原创,转载请注明出处,未经允许而盗用者追究法律责任. 很久之前写的了,留着有点浪费,共享之.编写者:李文栋P.S. OpenOffice粘贴过来后格式有些混乱. http://rayleeya ...
- hdu 1827 有向图缩点看度数
题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...
- (1)git
1.创建一个版本库 #创建一个文件夹 E:\>mkdir pythonGit #进入文件夹 E:\>cd pythonGit #把此目录创建成git版本库 E:\pythonGit> ...
- 小窥React360——用React创建360全景VR体验
前言 混迹VR届的发烧友兼开发者们一定不要错过这款FaceBook推出的跨端VR开发框架——React360,称为360全景体验框架更为准确,因为其前身是FaceBook和Oculus2017年 ...
- T3139 栈练习3 codevs
http://codevs.cn/problem/3139/ 题目描述 Description 比起第一题,本题加了另外一个操作,访问栈顶元素(编号3,保证访问栈顶元素时或出栈时栈不为空),现在给出这 ...