利用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做存储,封装使用更方便。
最新文章
- linux內核輸出soft lockup
- 小白Linux入门 二
- HTML-embed标签详解
- IT人的自我导向型学习:学习的4个层次
- PageBean分页组件
- Test Markdown Editor
- dispatch_get_current_queue 废弃
- 使用C#创建自定义背景色/形状的菜单栏与工具栏
- IE6 7 父级元素的overflow:hidden 是包不住子级的relative
- Day1 Python 介绍及基础
- 从输入 URL 到页面加载完成的过程中都发生了什么
- angular-dragon-drop.js 双向数据绑定拖拽的功能
- sql数据库设置自定义消息
- yii2.0 curd操作
- 《Redis 优化》
- LINUX 手动建立SWAP文件及删除
- VC++6 调用teststand api的方法
- Oracle 除数为0的处理(decode)
- 一款高效视频播放控件的设计思路(c# WPF版)
- BZOJ5297 CQOI2018社交网络(矩阵树定理)