Qt中QByteArray存储数据很方便,使用QBuffer存储大块数据更方便。QBuffer类包装了QByteArray类对象,实际存储还是使用了QByteArray,但QBuffer实现了QIODevice接口,其拥有丰富的读写接口,使操作更方便。

  主要需求是,存进去的数据接口函数参数要求是char* dat 和int datalength是形式,取出来的数据接口函数参数也是一样。

  qt里对基本数据格式都进行了封装,提供了如QChar、QBitArray、QByteArray类,使用起来也是很方便。如网络上接受到数据,都是帧流,处理数据时,需要按字节处理(因为通信协议多按字节定义),如上的缓存接口定义就比较合适。

  使用QBuffer+QLinkedList做一个缓存队列就非常容易了。

  下面给出代码:

  FrameStreamManager.cpp

  1. #include "FrameStreamManager.h"
  2.  
  3. FrameStreamManager::FrameStreamManager()
  4. {
  5.  
  6. }
  7.  
  8. FrameStreamManager::~FrameStreamManager()
  9. {
  10.  
  11. }
  12.  
  13. int FrameStreamManager::putFrame(char *in,int length)
  14. {
  15. int ret;
  16. QMutexLocker locker(&mutex);
  17.  
  18. QBuffer *qbuf = new QBuffer();
  19. qbuf->open(QBuffer::ReadWrite);
  20. ret = qbuf->write(in,length);
  21. qbuf->close();
  22.  
  23. list.append(qbuf);
  24.  
  25. return ret;
  26. }
  27.  
  28. int FrameStreamManager::getFrame(char *retbuf,int size)
  29. {
  30. QMutexLocker locker(&mutex);
  31. QBuffer *qbuf;
  32. int ret=;
  33.  
  34. if(list.size() > )
  35. {
  36. qbuf = list.takeFirst();
  37. qbuf->open(QBuffer::ReadWrite);
  38. ret = qbuf->read(retbuf,size);
  39. qbuf->close();
  40. delete qbuf;
  41. }
  42.  
  43. return ret;
  44. }
  45.  
  46. int FrameStreamManager::getFrameSize()
  47. {
  48. return list.size();
  49. }

  FrameStreamManager.h

  1. #ifndef FRAMESTREAMMANAGER_H
  2. #define FRAMESTREAMMANAGER_H
  3.  
  4. #include <QLinkedList>
  5. #include <QBuffer>
  6. #include <QByteArray>
  7. #include <QMutexLocker>
  8. #include <QMutex>
  9.  
  10. class FrameStreamManager
  11. {
  12. public:
  13. FrameStreamManager();
  14. ~FrameStreamManager();
  15.  
  16. private:
  17. QLinkedList<QBuffer*> list;
  18. QMutex mutex;
  19.  
  20. public:
  21. int putFrame(char *in,int length);
  22. int getFrame(char *rebuf,int size);
  23. int getFrameSize(void);
  24. };
  25.  
  26. #endif

  测试文件:

  mainwindow.cpp

  1. #include "mainwindow.h"
  2. #include <QLabel>
  3. #include <QtDebug>
  4. #include <QBuffer>
  5. #include <QPushButton>
  6.  
  7. MainWindow::MainWindow(QWidget *parent)
  8. : QMainWindow(parent)
  9. {
  10. this->setFixedSize(,);
  11. QLabel *label = new QLabel("hello you are",this);
  12. label->move(,);
  13.  
  14. QPushButton *btn1 = new QPushButton("put",this);
  15. connect(btn1, SIGNAL(clicked()), this, SLOT(btn1Clicked()));
  16. btn1->move(,);
  17.  
  18. QPushButton *btn2 = new QPushButton("show",this);
  19. connect(btn2,SIGNAL(clicked()),this,SLOT(btn2Clicked()));
  20. btn2->move(,);
  21.  
  22. QPushButton *btn3 = new QPushButton("get",this);
  23. connect(btn3,SIGNAL(clicked()),this,SLOT(btn3Clicked()));
  24. btn3->move(,);
  25.  
  26. for(int i=;i<;i++)
  27. defaultbuf[i] = ;
  28.  
  29. memset(retbuf,,);
  30.  
  31. /*// int BUFSIZE = 2048;
  32.  
  33. // QBuffer qbuf;
  34. // qbuf.open(QBuffer::ReadWrite);
  35.  
  36. // char *buf = (char*)malloc(BUFSIZE);
  37. // for(int i=0;i<BUFSIZE;i++)
  38. // {
  39. // buf[i] = 234;
  40. // }
  41.  
  42. // int ret = qbuf.write(buf,BUFSIZE);
  43. // qbuf.close();
  44. // qDebug()<<"ret = "<<ret;
  45.  
  46. // char *retbuf = (char *)malloc(BUFSIZE);
  47. // memset(retbuf,0,BUFSIZE);
  48. // qbuf.open(QBuffer::ReadWrite);
  49.  
  50. // ret = qbuf.read(retbuf,BUFSIZE);
  51. // qDebug()<<"ret = "<<ret;
  52. // for(int i=0;i<BUFSIZE;i++)
  53. // {
  54. // if(retbuf[i] != (char)234)
  55. // {
  56. // qDebug()<<"Error at "<<i<<" : "<<retbuf[i];
  57. // }
  58. // }
  59. // qbuf.close();
  60.  
  61. // free(buf);
  62. // free(retbuf); */
  63. }
  64.  
  65. MainWindow::~MainWindow()
  66. {
  67.  
  68. }
  69.  
  70. void MainWindow::btn1Clicked()
  71. {
  72. qDebug()<<"\nput frame!";
  73.  
  74. int len = fsm.putFrame(defaultbuf,);
  75. if(len != )
  76. qDebug()<<"put frame buf";
  77. }
  78.  
  79. void MainWindow::btn2Clicked()
  80. {
  81. qDebug()<<"\nshow frame list size!";
  82.  
  83. int len = fsm.getFrameSize();
  84. qDebug()<<"Now Frame Size = "<<len;
  85. }
  86.  
  87. void MainWindow::btn3Clicked()
  88. {
  89. qDebug()<<"\nget frame and check!";
  90.  
  91. int len = fsm.getFrame(retbuf,);
  92. if(len != )
  93. qDebug()<<"get frame returns "<<len;
  94. else
  95. {
  96. for(int i=;i<;i++)
  97. {
  98. if(retbuf[i] != )
  99. qDebug()<<" get data error at "<<i<<" : "<<retbuf[i];
  100. }
  101. }
  102.  
  103. memset(retbuf,,);
  104. }

  mainwindow.h

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3.  
  4. #include <QMainWindow>
  5. #include "FrameStreamManager.h"
  6.  
  7. class MainWindow : public QMainWindow
  8. {
  9. Q_OBJECT
  10.  
  11. public:
  12. MainWindow(QWidget *parent = );
  13. ~MainWindow();
  14.  
  15. private slots:
  16. void btn1Clicked();
  17. void btn2Clicked();
  18. void btn3Clicked();
  19.  
  20. private:
  21. FrameStreamManager fsm;
  22.  
  23. char defaultbuf[];
  24. char retbuf[];
  25. };
  26.  
  27. #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】P3116会议时间(拓扑排序,DP)

    题目链接 本题使用拓扑排序来规划DP顺序.设s[i][j]表示i步是否能走到j这个点,e[i][j]表示i步是否能走到j这个点——用第二条路径.因为要满足无后效性和正确性,只有第i个点已经全部更新完毕 ...

  2. [COI2007] Patrik 音乐会的等待 (单调栈,模拟)

    题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...

  3. 请问 内网的 dns服务器 为什么和 外网的dns服务器 一样??

    公司内的内网使用192.169.X.X的内网地址,但是在DNS段填写的是210.34.X.X,显然这是一个公网固定IP,我不明白的是:为什么内部网客户端使用的DNS服务器是公网上的IP呢?内网客户端能 ...

  4. 使用vue-cli创建项目(包含npm和cnpm的安装nodejs的安装)

    转:http://www.cnblogs.com/wisewrong/p/6255817.html vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue ...

  5. Modular Production Line

     Modular Production Line 时空限制: 1000ms /65536K   An automobile factory has a car production line. Now ...

  6. lnux 下 core文件

    1. core文件的简单介绍在一个程序崩溃时,它一般会在指定目录下生成一个core文件.core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的. 2. 开启或关闭core文件的生成用以下 ...

  7. Redis命令行之List

    一.Redis之List简介 1. List是简单的字符串列表,按照插入顺序排列. 2. 一个列表最多可存储232-1个元素(40多亿). 二.Redis之List命令行操作 Lrange:获取列表指 ...

  8. 实验十二 swing图形界面设计

    1.源程序 package information;import java.awt.Container;import java.awt.FlowLayout;import java.awt.event ...

  9. Java代码规范和质量检查插件-Checkstyle(官方资源)

    其实Checkstyle是一个JAR包,然后第三方开发者开发了Eclipse/IDEA的插件. 官网: https://github.com/checkstyle/checkstyle Eclipse ...

  10. 使用Maven运行Java main的方法(转)

    使用Maven运行Java Main的方法(既Java Application项目),可以有如下方式解决: 1.将Maven项目导入到eclipse中,然后直接项目右键[Run As]->[Ja ...