对QT中QBitArray类进行简单剖析
我们知道Qt中的QBitArray类支持在位(bit)的层次上进行数据操作。本文剖析该类在二进制文件读写时的一些要点。另外,在Qt中,QDataStream类对于二进制文件的读写提供了诸多便利,需要注意的是QBitArray的读写依赖于QDataStream类。
使用QBitArray向文件中写数据:
QFile file("C:\\Users\\lenovo\\Desktop\\测试");
file.open(QIODevice::WriteOnly);//只写
QDataStream input(&file);
QBitArray bit();//构造大小为5的位数组
bit[]=;bit[]=;bit[]=;bit[]=;bit[]=;
input<<bit;//向文件中写入数据10011
file.close();
使用QBitArray向文件中读数据:
QFile file("C:\\Users\\lenovo\\Desktop\\测试");
file.open(QIODevice::ReadOnly);//只读
QDataStream output(&file);
QBitArray bit;//此处不需要指定位数组的大小,后面解释
output>>bit;//从文件中读取数据,可以得到10011
file.close();
上面只是读写了一个简单的位数组,是最简单的例子。但是当我们需要连续多次的读写这种位数组时,甚至想要一位一位读取这些位信息时,该如何处理呢?
先明确一句话:在进行读操作时,无法根据指定的QBitArray位数组的大小(size)来读取。也就是说实际上读取到的size()大小,与自己设定的大小并不一致。(这个结论个人实验得出)
以如下代码为例:
QFile file("C:\\Users\\lenovo\\Desktop\\测试");//该文件中已经存在位信息10011
file.open(QIODevice::ReadOnly);//只读
QDataStream output(&file);
QBitArray bit();//此处我设置位数组的大小为3,我只想读取3位二进制信息
output>>bit;//读取
qDebug()<<bit.size();//输出结果为5,显然与我们希望的不一样。原因后面解释
file.close();
究竟是什么原因造成的呢??我们开始进入重点:分析这个原因我们需要分析QBitArray在文件中的编码规则。
每一个完整的QBitArray对象,存储进文件后,其编码格式都是固定的:位数组的大小+位数组的实际数据。以位数据10001为例:其编码为

(图片中每个数字代表四个位,用16进制表示)
1、4个字节存储该位数组的位数,00 00 00 05就表示这个位数组有5位
2、剩下部分存储具体的位数据。可是我们的数据是1001 1为什么存储成了19呢???原因如下:
存储QBitArray对象时,采用的是逆存储方式,即先存储后四个位信息,再存储前四个位信息。19中的 “1” 表示 “0001”,“9”表示“10001”
注意这种情况:
QFile file("C:\\Users\\lenovo\\Desktop\\测试");
file.open(QIODevice::WriteOnly);//只写
QDataStream input(&file);
QBitArray bit();//构造大小为5的位数组
bit[]=;bit[]=;bit[]=;bit[]=;bit[]=;
input<<bit[];//写入数据
这种情况下,向文件中写入了一个位信息,这里并没有写入完整的对象。那么存储时,也就没有完整的结构。其编码如下图:
相当于向文件写入了一个数字1。如果bit[0]=0,那么相当于向文件中写入了一个数字0。
总结:也就是说,每个QBitArray对象存储进文件后的结构都是确定了的。所以如果想一个位一个位的读取,那么就会破坏掉这个对象的编码结构,以至于出现读取错误的情况。想要正确的读取出所有的位信息,必须完整的读取每个QBitArray对象,所以在读取的时候我们不需要设置位数组的大小。也就是说,写入的时候写了多少个QBitArray对象,读取的时候就得用多少个QBitArray对象。
对QT中QBitArray类进行简单剖析的更多相关文章
- Qt中QScrollArea类的简单使用心得
平台:windows 64位 Qt版本:5.5.1 MinGW 32bit 根据自己目前的需求简单说下怎么在QScrollArea滚动窗口中实现多个控件的滚动显示,先看看最 ...
- java中Color类的简单总结
java中Color类的简单总结 1.颜色的常识 任何颜色都是由三原色组成(RGB),JAVA中支持224为彩色,即红绿蓝分量取值 介于0-255之间(8位表示) 2.Color类中的常量 publi ...
- Qt中事件分发源码剖析
Qt中事件分发源码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,而且进行分发,这些都是在exec中进行的. 以下举例说明: 1)首先看看以下一段演示样例代码: ...
- QT中QWidget类简介
一.详细描述 QWidget类是所有用户界面对象的基类.通俗的来讲,Qt基本上所有的UI类都是由QWidget继承出来的,而QWidget继承于QObject, 大家可以查阅Qt source 即可 ...
- <QT之Bug制造机>QT中串口类“QSerialPort”的学习笔记
QT5中已经增加了串口类QSrialPort,可以直接调用API函数进行快速开发. 1. 获取串口信息 Dialog::Dialog(QWidget *parent) : QDialog(parent ...
- 关于Opencv2.4.x中stitcher类的简单应用
1.opencv2.4以上版本有stitcher类,可以简单方便的实现图像的拼接,目前只是简单的测试一下stitcher类的拼接功能,也是纠结了好长时间,最终发现是要在链接库中加上opencv_sti ...
- 在Qt中配置TBB以及简单实用
最近本人在写离线光线追踪渲染器,但是Qt::QtConcurrent的功能有限,所以就尝试使用了一下,顺便分享一些经验. TBB里面的parallel_for非常适合光线追踪渲染器,而QtConcur ...
- Qt中新建类构造函数的初始化参数列表
使用Qt-creator自动生成一个窗体应用程序时会自动创建一个新的类,我的程序中名为MyDialog,类的定义为: #ifndef MYDIALOG_H #define MYDIALOG_H #in ...
- Spring中ClassPathXmlApplicationContext类的简单使用
转自:http://www.cnblogs.com/shyy/archive/2011/09/29/2453057.html 一.简单的用ApplicationContext做测试的话,获得Sprin ...
随机推荐
- C# 从零开始写 SharpDx 应用 画三角
原文:C# 从零开始写 SharpDx 应用 画三角 版权声明:博客已迁移到 https://blog.lindexi.com 欢迎访问.如果当前博客图片看不到,请到 https://blog.lin ...
- 05Dockerfile简介
Dockerfile是一个用于构建Docker镜像的文本文件,其中包含了创建Docker镜像的全部指令.基于这些指令,可以使用"docker build"命令来创建镜像. 一:用 ...
- 阿里云亮相2019联通合作伙伴大会,边缘计算等3款云产品助力5G时代产业数字化转型
4月23日,2019中国联通合作伙伴大会在上海正式开幕,本次大会以“合作不设限,共筑新生态”为主题,涉及5G.边缘计算.云计算.物联网.新媒体.人工智能.互联网化等各领域超过600家合作伙伴与3万名各 ...
- hdu 1077 (圆交)
Problem - 1077 我们可以知道,当这个单位圆可以覆盖到最多的点的时候,必定最少有两个点位于这个圆的圆周上,于是就有网上众多的O(N^3)的枚举两个在圆上的点的暴搜做法. 然而这题是可以用圆 ...
- 3、.net core 部署到IIS
1)下载对应的Hosting Bundle https://dotnet.microsoft.com/download/dotnet-core/2.2 2)VS发布项目,选择window平台环境 3 ...
- Python进阶04函数的参数对应
我们已经接触过函数(function)的参数(arguments)传递.当时我们根据位置,传递对应的参数.我们将接触更多的 参数传递方式. 回忆一下位置传递: def f(a,b,c): return ...
- D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数
我们不以权值建立主席树,而是区间端点作为值建立线段树,一个个插入a[i],我们发现这个数之前是存在的,就需要在上个版本的主席树上减去原来的位置,并加上现在的位置,这样我们在i版本的主席树,维护1-r中 ...
- Eclipse(Maven) web项目更改项目名称
1. 右键工程:Refactor->Rename,更改项目名称: 2. 修改项目目录下:.project文件 <?xml version="1.0" encoding= ...
- Activiti5----流程监听器与任务监听器
首先创建流程监听器和任务监听器的实体类,个人比较喜欢使用Delegate Expression方式,其他两种方式也可以 流程监听器 package org.mpc.final_activiti; im ...
- 在Linux/Unix上运行SuperSocket
SuperSocket通过(Mono 2.10或更新版本)来实现跨平台的特性 由于Unix/Linux不同于Windows上的文件路径格式,SuperSocket提供了专用于Unix/Linux系统上 ...