文本文件读写

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):移除监听的目录或文件列表;

图示

【嵌入式——QT】文件系统和文件读写-LMLPHP
【嵌入式——QT】文件系统和文件读写-LMLPHP
【嵌入式——QT】文件系统和文件读写-LMLPHP

代码示例

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();
}

03-13 16:48