QFile和QDataStream二进制文件读写第三集
想看更多精彩内容内容,锁定:
文件读写共计3集,想看全集记得去Qt专栏
一、QFile和QDataStream说明
除了文本文件,其他都称为二进制文件,QFile负责文件的IO设备接口,QDataStream 以数据流的方式读取文件内容或写入文件内容。QDataStream有两种格式:
【1】.stm ->写入时,使用Qt预定义的编码。[应用:表格]
【2】.dat ->写入时,使用二进制原本的格式。[应用:表格]
【3】QDataStream datastream(&file);//创建数据流栈对象
datastream.setVersion(QDataStream::Qt_5_9);//流版本号,写入和读取要兼容
【4】写时推荐使用<<,读取时>>,QDateStream还支持写:QBrush、QColor、QImage、 QIcon等。
【5】写文件时各种数据类型记住,读取时按照数据类型读取,去看文件是乱码,二进 制一般不支持在线看,除非使用第三方工具。
【6】Qt预定义编码stm,文件格式不透明,不知字节定义,支持的编程语言少。
【7】标准编码dat,文件格式透明,知道字节的定义,支持任何编程语言读写文件程序。
【8】dat读写时,需要指定字节顺序,QDataStream datastream(&file);
datastream.setByteOrder(QDataStream::LittleEndian);//小端字节序
小端序:低字节数据存放在内存低地址处;高字节存放在内存高地址处;
大端序:刚好相反;
【9】dat写文件:writeRawData()负责整形//writeBytes()负责字符串(推荐)
二、QFile和QDataStream举例.stm
main.c
#include "mainwindow.h"
#include <QApplication>
#include <QTextCodec>
int main(int argc, char *argv[])
{
//解决中文乱码
QTextCodec*codec =QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QDataStream>
#include <QDir>
#include <QLabel>
#include <QStandardItemModel>//数据模型
#include <QMessageBox>
#include <QTableView>
#include <QStringList>
private slots:
void on_PB_stm_clicked();
void on_PB_savestm_clicked();
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
//以Qt预定义编码保存stm文件
void MainWindow::on_PB_stm_clicked()
{
QString curPath = QDir::currentPath();//打开一个目录 并返回目录路径
qDebug()<<"curPath="<<curPath<<endl;
QString fileName = QFileDialog::getOpenFileName(this,"选择保存的文件",curPath,"文件类型(*.stm);;所有文件(*.*)");//返回文件的绝对路径
qDebug()<<"fileName="<<fileName<<endl;
if(fileName.isEmpty())
return;
if(saveStm(fileName))
QMessageBox::information(this,"提示","文件保存成功");
}
//保存stm文件
bool MainWindow::saveStm(QString &fileName)
{
QFile file(fileName);//创建文件栈对象
if(!(file.open(QIODevice::WriteOnly|QIODevice::Truncate)))
return false;
QDataStream datastream(&file);//创建数据流栈对象
datastream.setVersion(QDataStream::Qt_5_9);//流版本号,写入和读取要兼容
qint16 rowCount = 1;
qint16 colCount = 2;
qreal speed =12.7;
QString str ="今天写stm";
//追加方式
datastream<<rowCount;
datastream<<colCount;
datastream<<str;
datastream<<speed;
file.close();
return true;
}
//保存stm文件
void MainWindow::on_PB_savestm_clicked()
{
QString curPath = QDir::currentPath();
qDebug()<<"curPath="<<curPath<<endl;
QString fileName = QFileDialog::getOpenFileName(this,"选择保存的文件",curPath,"文件类型(*.stm);;所有文件(*.*)");
qDebug()<<"fileName="<<fileName<<endl;
if(fileName.isEmpty())
return ;
if(openStm(fileName))
QMessageBox::information(this,"提示","文件打开成功");
}
//打开stm文件,读取内容
bool MainWindow::openStm(QString &fileName)
{
QFile file(fileName);//创建文件栈对象
if(!(file.open(QIODevice::ReadOnly)))
return false;
QDataStream datastream(&file);//创建数据流栈对象
datastream.setVersion(QDataStream::Qt_5_9);//流版本号,写入和读取要兼容
qint16 rowCount ;
qint16 colCount;
QString str ;
qreal speed ;
//读取一定要和写时:数据类型相同,箭头相反
datastream>>rowCount;
datastream>>colCount;
datastream>>str;
datastream>>speed;
QString add = tr("qint16=%1 qint16=%2 str=%3 speed=%4").arg(rowCount).arg(colCount).arg(str).arg(speed);
ui->textEdit->append(add);
file.close();
return true;
}
截图:
写入文件
读取文件
三、QFile和QDataStream举例.dat
头文件内容:
#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QDataStream>
#include <QDir>
#include <QLabel>
#include <QMessageBox>
private slots:
void on_PB_writedat_clicked();
void on_PB_readdat_clicked();
private:
bool saveDat(QString & fileName);
bool openDat(QString &fileName);
mainwindow.cpp文件
/*=======================================================================*/
//保存dat文件
void MainWindow::on_PB_writedat_clicked()
{
QString curPath = QDir::currentPath();
qDebug()<<"curPath="<<curPath<<endl;
QString fileName = QFileDialog::getOpenFileName(this,"选择写入的文件",curPath,"文件类型(*.dat);;所有文件(*.*)");
qDebug()<<"fileName="<<fileName<<endl;
if(fileName.isEmpty())
return;
if(saveDat(fileName))
QMessageBox::information(this,"提示","文件写入成功");
}
bool MainWindow::saveDat(QString &fileName)
{
QFile file(fileName);//创建文件栈对象
if(!(file.open(QIODevice::WriteOnly|QIODevice::Truncate)))
return false;
QDataStream datastream(&file);//创建数据流栈对象
datastream.setByteOrder(QDataStream::LittleEndian);//小端字节序 X86
//datastream.setByteOrder(QDataStream::BigEndian);//大端字节序 其他嵌入式平台
//开始写入
qint16 rowCount = 3;
qDebug()<<"rowCount->sizeof="<<sizeof(qint16)<<endl;//2字节
qint16 colCount = 4;
qreal speed =15.7;
qDebug()<<"speed->sizeof="<<sizeof(qreal)<<endl;//8字节
QString str ="今天写dat";
qDebug()<<"str->sizeof="<<sizeof(QString)<<endl;//4字节
//写入文件流
datastream.writeRawData((char *)&rowCount,sizeof(qint16));
datastream.writeRawData((char *)&colCount,sizeof(qint16));
datastream.writeRawData((char *)&speed,sizeof(qreal));
//读取时,如果不知写入时的大小,可能读取错,测试无法获取数据
//datastream.writeRawData((char *)str,str.length());//1
//写入时大小已知,方便读取
datastream.writeBytes(str.toUtf8(),str.toUtf8().length());//写入字符串 2
file.close();
return true;
}
//打开dat文件
void MainWindow::on_PB_readdat_clicked()
{
QString curPath = QDir::currentPath();
qDebug()<<"curPath="<<curPath<<endl;
QString fileName = QFileDialog::getOpenFileName(this,"选择保存的文件",curPath,"文件类型(*.dat);;所有文件(*.*)");
qDebug()<<"fileName="<<fileName<<endl;
if(fileName.isEmpty())
return;
if(openDat(fileName))
QMessageBox::information(this,"提示","文件保存成功");
}
bool MainWindow::openDat(QString &fileName)
{
QFile file(fileName);//创建文件栈对象
if(!(file.open(QIODevice::ReadOnly)))
return false;
QDataStream datastream(&file);//创建数据流栈对象
datastream.setByteOrder(QDataStream::LittleEndian);//小端模式
qint16 rowCount , colCount ;
qreal speed ;
//读取开始 怎么写的则么读
datastream.readRawData((char *)&rowCount,sizeof(qint16));
datastream.readRawData((char *)&colCount,sizeof(qint16));
datastream.readRawData((char *)&speed,sizeof(qreal));
qDebug()<<"speed = "<<speed<<endl;
//错误形式
//datastream.readRawData((char *)&str,sizeof(QString));
//datastream.readRawData((char *)&str,str.length());
char *buf = nullptr;
uint strlen;
datastream.readBytes(buf,strlen);//同时读取内容,和大小
QString str =QString::fromLocal8Bit(buf,strlen);//字节数组转化为字符串
qDebug()<<"str = "<<buf<<"strlen = "<<strlen<<endl;
ui->textEdit->append(QString("rowCount=%1 colCount=%2 speed=%3 list=%4 ").arg(rowCount).arg(colCount)
.arg(speed).arg(str));
buf=nullptr;//对指针的操作需要复位 防止野指针
file.close();
return true;
}
截图:
写入文件
读取文件:
文件读写三集 完