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做数据块存储队列的更多相关文章

  1. HDFS中数据节点数据块存储示例

    数据块在数据节点上是按照如下方式存储的. 首先是一个存储的根目录/Hadoop/data/dfs/dn,如下图所示: 接着进入current目录,如下图所示: 再进入后续的BP-433072574-1 ...

  2. [转]Oracle数据块体系的详细介绍

    数据块概述Oracle对数据库数据文件(datafile)中的存储空间进行管理的单位是数据块(data block).数据块是数据库中最小的(逻辑)数据单位.与数据块对应的,所有数据在操作系统级的最小 ...

  3. Ext2文件系统布局,文件数据块寻址,VFS虚拟文件系统

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

  4. Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统

    前言 我们知道HDFS集群中,所有的文件都是存放在DN的数据块中的.那我们该怎么去查看数据块的相关属性的呢?这就是我今天分享的内容了 一.HDFS中数据块概述 1.1.HDFS集群中数据块存放位置 我 ...

  5. HDFS源码分析数据块校验之DataBlockScanner

    DataBlockScanner是运行在数据节点DataNode上的一个后台线程.它为所有的块池管理块扫描.针对每个块池,一个BlockPoolSliceScanner对象将会被创建,其运行在一个单独 ...

  6. mongodb 数据块的迁移流程介绍

    1. 基本概念 1.1 Chunk(数据块) 表示特定服务器上面,连续范围的分片键值所包含的一组数据,是一个逻辑概念. 例如,某数据块记录如下: { "_id" : "c ...

  7. vuex数据持久化存储

    想想好还是说下vuex数据的持久化存储吧.依稀还记得在做第一个vue项目时,由于刚刚使用vue,对vue的一些基本概念只是有一个简单的了解.当涉及到非父子组件之间通信时,选择了vuex.只是后来竟然发 ...

  8. 利用php的序列化和反序列化来做简单的数据本地存储

    利用php的序列化和反序列化来做简单的数据本地存储 如下程序可以做为一个工具类 /** * 利用php的序列化和反序列化来做简单的数据本地存储 */ class objectdb { private ...

  9. 【oracle11g,17】存储结构: 段的类型,数据块(行连接、行迁移,块头),段的管理方式,高水位线

    一.段的类型: 1.什么是段:段是存储单元. 1.段的类型有: 表 分区表 簇表 索引 索引组织表(IOT表) 分区索引 暂时段 undo段 lob段(blob ,clob) 内嵌表(record类型 ...

随机推荐

  1. 刷题总结——营业额统计(bzoj1588)

    题目: Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成 ...

  2. Dynamic Rankings(zoj 2112)

    题意:带修改的第K大 #include<cstdio> #include<iostream> #include<cstring> #define N 400010 ...

  3. GT考试 BZOJ 1009

    GT考试 [问题描述] 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0< ...

  4. Linux 下tomcat的配置

    参考文档:http://blog.csdn.net/jeamking/article/details/7881196 http://www.cnblogs.com/panxuejun/p/618641 ...

  5. Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) E. Vasya and Good Sequences

    题目链接 官网题解写的好清楚,和昨晚Aguin说的一模一样…… 这题只和每个数1的个数有关,设每个数1的个数的数组为$b$,就是首先一段如果是好的,要满足两个条件: 1.这一段$b$数组和为偶数,因为 ...

  6. codeforces 1041 e 构造

    Codeforces 1041 E 构造题. 给出一种操作,对于一棵树,去掉它的一条边.那么这颗树被分成两个部分,两个部分的分别的最大值就是这次操作的答案. 现在给出一棵树所有操作的结果,问能不能构造 ...

  7. 模板题 Problem I Link Cut Tree

    @(XSY)[LCT] Description 你们这么轻松A了前两题,要是AK了我可就惨了,所以这道题一定要是难(shui)题.那出什么难题呢?有了,这样吧,第一题是数,第二题是树,那我就出个同时含 ...

  8. VMware Workstation 虚拟机设置连接U盘

    首先确保主机有开启"VMware USB Arbitration Service"服务,而且在执行中. 如图:(我的系统是win8.1 ) 在VMware Workstation虚 ...

  9. python遍历两个列表,若长度不等,用None填充

    zip经常会遇到截断问题,如:a = [1,2,3], b = [4,5,6,7],则zip(a,b) = [(1, 4), (2, 5), (3, 6)] 可考虑使用map: map(lambda ...

  10. BUPT复试专题—哈夫曼编码(2009)

    题目描述 哈夫曼编码中  平均码长=码长×码字出现的概率 如:ABCDE 五个字符的出现次数分别为50 20 5 10 15 那么,其哈夫曼编码为A:0   B:10   C:1110   D:111 ...