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. 【Luogu】P3856公共子串(DP)

    题目链接 DP.设last[i][j]是第i个串字符'j'所在的最后的位置,f[i][j][k]是第一个串匹配到i,第二个串匹配到j,第三个串匹配到k,最多的公共子串数. 那么我们三重循环i.j.k, ...

  2. bzoj1064【Noi2008】假面舞会

    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1064 给一个有向图染色,每个点的后继必须相同,问至少&至多有多少种染色方案 sol: ...

  3. bzoj1225 [HNOI2001] 求正整数

    1225: [HNOI2001] 求正整数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 762  Solved: 313[Submit][Statu ...

  4. AtCoder Regular Contest 095E - Symmetric Grid

    $n \leq 12,m \leq 12$,$n$行$m$列小写字母,现可做无数次操作:交换两行:交换两列.问是否有可能把他变成中心对称的. 没有去想分组枚举的复杂度QAQ 行和列的操作顺序是随意的. ...

  5. angular中事件戳转日期的格式

    本地化日期格式化: ({{ today | date:'medium' }})Nov 19, 2015 3:57:48 PM ({{ today | date:'short' }})11/19/15 ...

  6. laravel 查询构造器

    //查询构造器public function query(){ $bool = DB::table('student')->insert([ ['name' => '王五', 'age' ...

  7. android的系统学习

    先从Android的应用开发开始,等到对应用掌握的比较熟悉了,开始慢慢阅读一些Android 应用框架层的源代码,然后再渐渐往下去了解Android的JNI.Libraries.Dalvik虚拟机.H ...

  8. sring->list->del->string->int:解析左右编码器的,和#号

    #def test_sprintf(): import string ' str1="1234567890," print'str1 is',str1 list_raw=list( ...

  9. [转] java中volatile关键字的含义

    在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...

  10. python实现网速控制,限制上传下载速度

    对于python的web,比如flask使用的werkzeug,首先找到wsgi的请求和响应的代码,使用算法实现大文件的小速率上传和下载 考虑python实现socket限流 关于限速的讨论:http ...