【嵌入式——QT】文件系统和文件读写
文本文件读写
QT提供了两种读写纯文本文件的基本方法,一种是用QFile类的IODevice读写功能直接进行读写,另一种是利用QFile和QTextStream结合起来,用流(Stream)的方法进行文件读写。
二进制文件读写
除了文本文件之外,其他需要按照一定的格式定义读写的文件都称为二进制文件,每种格式的二进制文件都有自己的格式定义,写入数据时按照一定的顺序写入,读出时也按照相应的顺序读出。
文件目录操作
Qt为文件和目录操作提供了一些类,利用这些类可以方便的实现一些操作.
QCoreApplication
用于提取应用程序路径,程序名等文件信息,是所有应用程序的基类。
- applicationDirPath():返回应用程序启动路径;
- applicationFilePath():返回应用程序的带有目录的完整文件名;
- applicationName():返回应用程序名称,无路径无后缀;
- libraryPaths():返回动态加载库文件时,应用程序搜索的目录列表;
- organizationName():返回应用程序机构名;
- setOrganizationName(const QString &orgName):设置应用程序机构名;
- exit(int returnCode = 0):退出应用程序;
QFile
除了打开文件操作外,QFile还有复制文件,删除文件等功能。
- copy(const QString &fileName, const QString &newName):复制文件;
- rename(const QString &oldName, const QString &newName):重命名文件;
- remove(const QString &fileName):删除一个文件;
- exists(const QString &fileName):判断文件是否存在;
- setPermissions(const QString &fileName, QFileDevice::Permissions permissions):设置文件权限;
- permissions(const QString &fileName):返回文件的权限;
QFileInfo
用于提取文件的信息,包括路径,文件名,后缀等。
- setFile(const QString &file):设置文件名;
- absoluteFilePath() const:返回带有文件名的绝对路径;
- absolutePath() const:返回绝对路径不带文件名;
- baseName() const:返回文件基名;
- fileName() const:返回去除路径的文件名;
- filePath() const:返回包含路径的文件名;
QDir
用于提取目录或文件信息,获取一个目录下的文件或目录列表,创建或删除目录和文件,文件重命名等操作。
QTemporaryDir和QTemporaryFile
用于创建临时目录和临时文件。
- setAutoRemove(bool b):设置是否自动删除;
- path() const:返回创建的临时目录名称;
- remove():删除此临时目录机及其下面所有文件;
QFileSystemWatcher
文件和目录监听类,监听目录下文件的添加,删除等变化,监听文件修改变化。
- addPath(const QString &path):添加一个监听的目录或文件;
- addPaths(const QStringList &paths):添加需要监听的目录或文件列表;
- directories() const:返回监听的目录列表;
- files() const:返回监听的文件列表;
- removePath(const QString &path):移除监听的目录或文件;
- removePaths(const QStringList &paths):移除监听的目录或文件列表;
图示
代码示例
TextFileDialog.h
#ifndef TEXTFILEDIALOG_H
#define TEXTFILEDIALOG_H
#include <QDialog>
namespace Ui
{
class TextFileDialog;
}
class TextFileDialog : public QDialog
{
Q_OBJECT
public:
explicit TextFileDialog(QWidget* parent = nullptr);
~TextFileDialog();
private slots:
void on_pushButtonFileOpen_clicked();
void on_pushButtonFileSave_clicked();
void on_pushButtonStreamOpen_clicked();
void on_pushButtonStreamSave_clicked();
private:
Ui::TextFileDialog* ui;
};
#endif // TEXTFILEDIALOG_H
TextFileDialog.cpp
#include "TextFileDialog.h"
#include "ui_TextFileDialog.h"
#include <QDir>
#include <QFileDialog>
#include <QTextStream>
TextFileDialog::TextFileDialog(QWidget* parent)
: QDialog(parent)
, ui(new Ui::TextFileDialog)
{
ui->setupUi(this);
}
TextFileDialog::~TextFileDialog()
{
delete ui;
}
void TextFileDialog::on_pushButtonFileOpen_clicked()
{
QString curPath = QDir::currentPath();
QString fileName = QFileDialog::getOpenFileName(this, u8"打开一个文件", curPath);
if(fileName.isEmpty()) {
return;
}
//用IODevice方式打开文件
QFile file(fileName);
if(!file.exists()) {
return;
}
/**
ReadOnly 只读方式打开文件 用于载入文件
WriteOnly 只写方式打开文件,用于保存文件
ReadWrite 读写方式打开文件
Append 以添加模式打开文件,新写入文件的数据添加到文件尾部
Truncate 截取方式打开文件,文件原有的内容全部被删除
Text 以文本方式打开文件,读取时"\n"被自动翻译为换行符,写入时字符串结束会自动翻译为系统平台的编码 如Windows下是"\r\n"
**/
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return;
}
ui->plainTextEdit->setPlainText(file.readAll());
file.close();
}
void TextFileDialog::on_pushButtonFileSave_clicked()
{
QString curPath = QDir::currentPath();
QString fileName = QFileDialog::getSaveFileName(this, u8"保存一个文件", curPath);
if(fileName.isEmpty()) {
return;
}
//用IODevice方式保存文件
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return;
}
QString str = ui->plainTextEdit->toPlainText();
QByteArray strBytes = str.toUtf8();
file.write(strBytes, strBytes.length());
file.close();
}
void TextFileDialog::on_pushButtonStreamOpen_clicked()
{
QString curPath = QDir::currentPath();
QString fileName = QFileDialog::getOpenFileName(this, u8"打开一个文件", curPath);
if(fileName.isEmpty()) {
return;
}
//用QTextStream打开文本文件
QFile file(fileName);
if(!file.exists()) {
return;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return;
}
//用文本流读取文件
QTextStream stream(&file);
//自动检测Unicode,才能显示汉字
stream.setAutoDetectUnicode(true);
//读取一行
// stream.readLine();
ui->plainTextEdit->setPlainText(stream.readAll());
file.close();
}
void TextFileDialog::on_pushButtonStreamSave_clicked()
{
QString curPath = QDir::currentPath();
QString fileName = QFileDialog::getSaveFileName(this, u8"保存一个文件", curPath);
if(fileName.isEmpty()) {
return;
}
QFile file(fileName);
if(!file.exists()) {
return;
}
if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return;
}
QTextStream stream(&file);
stream.setAutoDetectUnicode(true);
QString str = ui->plainTextEdit->toPlainText();
//写入文本流
stream<<str;
file.close();
}
BinaryFileDialog.h
#ifndef BINARYFILEDIALOG_H
#define BINARYFILEDIALOG_H
#include <QDialog>
namespace Ui
{
class BinaryFileDialog;
}
class BinaryFileDialog : public QDialog
{
Q_OBJECT
public:
explicit BinaryFileDialog(QWidget* parent = nullptr);
~BinaryFileDialog();
private slots:
void on_saveStm_clicked();
void on_readStm_clicked();
void on_saveDat_clicked();
void on_readDat_clicked();
private:
Ui::BinaryFileDialog* ui;
};
#endif // BINARYFILEDIALOG_H
BinaryFileDialog.cpp
#include "BinaryFileDialog.h"
#include "ui_BinaryFileDialog.h"
#include <QMessageBox>
#include <QFile>
#include <QDir>
#include <QFileDialog>
#include <QDebug>
BinaryFileDialog::BinaryFileDialog(QWidget* parent)
: QDialog(parent)
, ui(new Ui::BinaryFileDialog)
{
ui->setupUi(this);
}
BinaryFileDialog::~BinaryFileDialog()
{
delete ui;
}
void BinaryFileDialog::on_saveStm_clicked()
{
QString curPath=QDir::currentPath();
QString aFileName=QFileDialog::getSaveFileName(this, tr(u8"选择保存文件"), curPath,
u8"Qt预定义编码数据文件(*.stm)");
if(aFileName.isEmpty()) {
return;
}
QFile aFile(aFileName); //以文件方式读出
if(!(aFile.open(QIODevice::WriteOnly | QIODevice::Truncate))) {
return;
}
QDataStream aStream(&aFile);
aStream.setVersion(QDataStream::Qt_5_9); //设置版本号,写入和读取的版本号要兼容
qint16 rowCount=6; //数据模型行数
qint16 colCount=5; //数据模型列数
aStream<<rowCount; //写入文件流,行数
aStream<<colCount;//写入文件流,列数
//获取表头文字
for(int i = 0; i<colCount; i++) {
QString str="demo"+QString::number(i);//获取表头文字
aStream<<str; //字符串写入文件流,Qt预定义编码方式
}
//获取数据区的数据
for(int i=0; i<rowCount; i++) {
qint16 ceShen=1;//qint16类型
aStream<<ceShen;// 写入文件流,qint16
qreal chuiShen=1;//qreal 类型
aStream<<chuiShen;//写入文件流, qreal
qreal fangWei=1.0;
aStream<<fangWei;//写入文件流, qreal
qreal weiYi=2.0;
aStream<<weiYi;//写入文件流, qreal
QString zhiLiang="demo";
aStream<<zhiLiang;// 写入文件流,字符串
bool quYang=true; //true or false
aStream<<quYang;// 写入文件流,bool型
}
aFile.close();
}
void BinaryFileDialog::on_readStm_clicked()
{
QString curPath=QDir::currentPath();
//调用打开文件对话框打开一个文件
QString aFileName=QFileDialog::getOpenFileName(this, tr("打开一个文件"), curPath,
"流数据文件(*.stm)");
if(aFileName.isEmpty()) {
return;
}
QFile aFile(aFileName); //以文件方式读出
if(!(aFile.open(QIODevice::ReadOnly))) {
return ;
}
QDataStream aStream(&aFile); //用文本流读取文件
aStream.setVersion(QDataStream::Qt_5_9); //设置流文件版本号
qint16 rowCount, colCount;
aStream>>rowCount; //读取行数
aStream>>colCount; //列数
//获取表头文字
QString str;
for(int i=0; i<colCount; i++) {
aStream>>str; //读取表头字符串
}
//获取数据区文字,
qint16 ceShen;
qreal chuiShen;
qreal fangWei;
qreal weiYi;
QString zhiLiang;
bool quYang;
for(int i=0; i<rowCount; i++) {
aStream>>ceShen;//读取测深, qint16
aStream>>chuiShen;//垂深,qreal
aStream>>fangWei;//方位,qreal
aStream>>weiYi;//位移,qreal
aStream>>zhiLiang;//固井质量,QString
aStream>>quYang;//bool
}
aFile.close();
}
void BinaryFileDialog::on_saveDat_clicked()
{
QString curPath=QDir::currentPath();
//调用打开文件对话框选择一个文件
QString aFileName=QFileDialog::getSaveFileName(this, tr(u8"选择保存文件"), curPath, u8"二进制数据文件(*.dat)");
if(aFileName.isEmpty()) {
return;
}
QFile aFile(aFileName); //以文件方式读出
if(!(aFile.open(QIODevice::WriteOnly))) {
return ;
}
QDataStream aStream(&aFile); //用文本流读取文件
aStream.setByteOrder(QDataStream::LittleEndian);//windows平台
qint16 rowCount=6;
qint16 colCount=5;
aStream.writeRawData((char*)&rowCount, sizeof(qint16)); //写入文件流
aStream.writeRawData((char*)&colCount, sizeof(qint16));//写入文件流
//获取表头文字
// QString str;
QByteArray btArray;
for(int i=0; i<colCount; i++) {
QString str="demo"; //获取表头文字
btArray=str.toUtf8(); //转换为字符数组
aStream.writeBytes(btArray, btArray.length()); //写入文件流,长度uint型,然后是字符串内容
}
//获取数据区文字
qint8 yes=1, no=0; //分别代表逻辑值 true和false
for(int i=0; i<rowCount; i++) {
qint16 ceShen=1;//qint16类型
aStream.writeRawData((char*)&ceShen, sizeof(qint16));//写入文件流
qreal chuiShen=1;//qreal 类型
aStream.writeRawData((char*)&chuiShen, sizeof(qreal));//写入文件流
qreal fangWei=1.0;
aStream.writeRawData((char*)&fangWei, sizeof(qreal));
qreal weiYi=2.0;
aStream.writeRawData((char*)&weiYi, sizeof(qreal));
QString zhiLiang="demo";
btArray=zhiLiang.toUtf8();
aStream.writeBytes(btArray, btArray.length());
bool quYang=true; //true or false
if(quYang) {
aStream.writeRawData((char*)&yes, sizeof(qint8));
} else {
aStream.writeRawData((char*)&no, sizeof(qint8));
}
}
aFile.close();
}
void BinaryFileDialog::on_readDat_clicked()
{
QString curPath=QDir::currentPath();
//调用打开文件对话框选择一个文件
QString aFileName=QFileDialog::getSaveFileName(this, tr(u8"选择打开文件"), curPath, u8"二进制数据文件(*.dat)");
if(aFileName.isEmpty()) {
return;
}
QFile aFile(aFileName); //以文件方式读出
if(!(aFile.open(QIODevice::ReadOnly))) {
return ;
}
QDataStream aStream(&aFile); //用文本流读取文件
aStream.setByteOrder(QDataStream::LittleEndian);
qint16 rowCount, colCount;
aStream.readRawData((char*)&rowCount, sizeof(qint16));
aStream.readRawData((char*)&colCount, sizeof(qint16));
//获取表头文字,但是并不利用
char* buf;
uint strLen; //也就是 quint32
for(int i=0; i<colCount; i++) {
aStream.readBytes(buf, strLen); //同时读取字符串长度,和字符串内容
QString str=QString::fromLocal8Bit(buf, strLen); //可处理汉字
}
//获取数据区数据
qint16 ceShen;
qreal chuiShen;
qreal fangWei;
qreal weiYi;
QString zhiLiang;
qint8 quYang; //分别代表逻辑值 true和false
for(int i=0; i<rowCount; i++) {
aStream.readRawData((char*)&ceShen, sizeof(qint16)); //测深
qDebug()<<"ceShen"<<ceShen;
aStream.readRawData((char*)&chuiShen, sizeof(qreal)); //垂深
qDebug()<<"chuiShen"<<ceShen;
aStream.readRawData((char*)&fangWei, sizeof(qreal)); //方位
qDebug()<<"fangWei"<<fangWei;
aStream.readRawData((char*)&weiYi, sizeof(qreal)); //位移
qDebug()<<"weiYi"<<weiYi;
aStream.readBytes(buf, strLen); //固井质量
zhiLiang=QString::fromLocal8Bit(buf, strLen);
qDebug()<<"zhiLiang"<<zhiLiang;
aStream.readRawData((char*)&quYang, sizeof(qint8)); //测井取样
qDebug()<<"quYang"<<quYang;
}
aFile.close();
}