• 利用QBuffer和QLinkedList做数据块存储队列


      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=0;
    33 
    34     if(list.size() > 0)
    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 }
    View Code

      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 
    27 #endif
    View Code

      测试文件:

      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(320,240);
     11     QLabel *label = new QLabel("hello you are",this);
     12     label->move(0,0);
     13 
     14     QPushButton *btn1 = new QPushButton("put",this);
     15     connect(btn1, SIGNAL(clicked()), this, SLOT(btn1Clicked()));
     16     btn1->move(0,25);
     17 
     18     QPushButton *btn2 = new QPushButton("show",this);
     19     connect(btn2,SIGNAL(clicked()),this,SLOT(btn2Clicked()));
     20     btn2->move(0,60);
     21 
     22     QPushButton *btn3 = new QPushButton("get",this);
     23     connect(btn3,SIGNAL(clicked()),this,SLOT(btn3Clicked()));
     24     btn3->move(0,95);
     25 
     26     for(int i=0;i<512;i++)
     27         defaultbuf[i] = 100;
     28 
     29     memset(retbuf,0,512);
     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()<<"
    put frame!";
     73 
     74     int len = fsm.putFrame(defaultbuf,512);
     75     if(len != 512)
     76         qDebug()<<"put frame buf";
     77 }
     78 
     79 void MainWindow::btn2Clicked()
     80 {
     81     qDebug()<<"
    show frame list size!";
     82 
     83     int len = fsm.getFrameSize();
     84     qDebug()<<"Now Frame Size = "<<len;
     85 }
     86 
     87 void MainWindow::btn3Clicked()
     88 {
     89     qDebug()<<"
    get frame and check!";
     90 
     91     int len = fsm.getFrame(retbuf,512);
     92     if(len != 512)
     93         qDebug()<<"get frame returns "<<len;
     94     else
     95     {
     96         for(int i=0;i<512;i++)
     97         {
     98             if(retbuf[i] != 100)
     99                 qDebug()<<" get data error at "<<i<<" : "<<retbuf[i];
    100         }
    101     }
    102 
    103     memset(retbuf,0,512);
    104 }
    View Code

      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 = 0);
    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[512];
    24     char retbuf[512];
    25 };
    26 
    27 #endif // MAINWINDOW_H
    View Code

      

      QByteArray也是可以完成同样功能,QByteArray有如下函数,QByteArray & QByteArray::append(const char *str,int len) 和char * QByteArray::data()。就是QByteArray会在返回的char* 数据后自动加‘’,但int QByteArray::size()返回来的数是不含'',利用size()函数和data()封装一下就可以达到上面QBuffer达到的效果。

      而且使用QByteArray有个好处,QByteArray重载了操作符=,所以FrameStreamManager里的list可以这样定义-->QLinkedList<QByteArray> list。从队列中取数据时可以直接写QByteArray tmp = list.takeFirst();而QBuffer没有重载=操作符,QBuffer tmp = list.takeFirst();这样就写就会直接报错。定义队列时就必须改成上面那样,就需要自己管理内存了。同时,使用QBuffer还需要打开和关闭设备。

      综上,队列中使用QByteArray做存储,封装使用更方便。

           

  • 相关阅读:
    FPGA学习之基本结构
    凸优化和机器学习
    第6篇如何访问pod
    吉日嘎拉DotNet.BusinessV4.2中的一处bug,及我的修复和扩展
    吉日嘎拉C#快速开发平台V4.0到V4.2升级记
    布隆过滤器简介及实现-----源自数学之美
    poj [1753]
    Zookeeper Hello World
    获取用户真实IP,php实现
    mysql中engine=innodb和engine=myisam的区别
  • 原文地址:https://www.cnblogs.com/kanite/p/7657207.html
Copyright © 2020-2023  润新知