QT中的文件操作QFile、QDataStream、QTextStream、QBuffer、QDir

文件操作概述

1、Qt中IO操作的处理方式

(1)、Qt通过统一的接口简化了文件与外部设备的操作方式

(2)、Qt中的文件被看做是一种特殊的外部设备

(3)、Qt中的文件操作与外部设备操作相同

2、IO操作中的关键函数接口

注意:IO操作的本质:连续存储空间的数据读写

3、Qt中IO设备类型

(1)、顺序存储设备:只能从头开始顺序读写数据,不能指定数据的读写位置(串口)

(2)、随机存储设备:可以定位到任意位置进行数据读写(seek function函数)(文件)

4、Qt中IO设备 的继承层次图

5、QT文件操作类型

QFile

QFile是Qt中用于文件操作的类

QFile直接支持文本文件:文件内容是可读的文本字符、

和数据文件:文件内容是直接的二进制数据的读写

QFineInfo用于读取文件属性信息
QTemPoraryFile安全创建全局唯一的临时文件、临时文件用于大数据传递或者进程间通信的场合
QTextStream

写入的数据全部转化为可读文本

QDataStream写入的数据根据类型转换为二进制
QBuffer

缓冲区的本质为一段连续的存储空间、QBuffer是qt中缓冲区相关的类

QDir是Qt中功能强大的目录操作类
QFileSystemWatcher用于监控文件和目录的状态变化(内容、重命名、删除)

QFile操作

 mainwindow.cpp:

#include "mainwindow.h"
#include <QApplication>

#define chineseToQString(pChineseText)  QTextCodec::codecForName("GB2312")->toUnicode(pChineseText)
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setWindowTitle("qfile test");
    QWidget* w=new QWidget;
    setCentralWidget(w);

    buttonRead->setText("buttonRead");
    buttonWrite->setText("buttonWrite");
    QHBoxLayout* hlayout=new QHBoxLayout;
    hlayout->addStretch(1);
    hlayout->addWidget(buttonRead);
    hlayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));
    hlayout->addWidget(buttonWrite);
    hlayout->addStretch(1);

    QVBoxLayout*container = new QVBoxLayout();
    container->addLayout(hlayout);
    container->addWidget(textEdit);
    centralWidget()->setLayout(container);
    this->resize(600, 400);

    connect(buttonRead,&QPushButton::clicked,this,&MainWindow::on_readData);
    connect(buttonWrite,&QPushButton::clicked,this,&MainWindow::on_writeData);
}

void MainWindow::on_readData()
{
    QString path = QFileDialog::getOpenFileName(this,"open", "../", "TXT(*.txt)");
    if(path.isEmpty() == false){
        QFile file(path); //文件对象
        bool isOk = file.open(QIODevice::ReadOnly);//打开文件,只读方式
        if(isOk == true) {
#if 0
            QByteArray array = file.readAll();//读文件,默认只识别utf8编码
            textEdit->setText(QString(array)); //显示到编辑区
            textEdit->setText(array);
#endif
            QByteArray array;
            while( file.atEnd() == false) {
                //读一行
                array += file.readLine();
            }
            textEdit->setText(array);
        }
        file.close();//关闭文件

        //获取文件信息
        QFileInfo info(path);
        qDebug() << "文件路径:"<< info.path();
        qDebug() << "文件名字:" << info.fileName().toUtf8().data();
        qDebug() << "文件后缀:" << info.suffix();
        qDebug() << "文件大小:" << info.size();
        qDebug() << "文件创建时间:" <<
        info.created().toString("yyyy-MM-dd hh:mm:ss");
        qDebug() << info.exists();
        qDebug() << info.isFile();
        qDebug() << info.isReadable();
        qDebug() << info.isWritable();
        qDebug() << info.lastRead();
        qDebug() << info.lastModified();//最后修改时间
        qDebug() << info.isExecutable(); // 是否是可执行文件
        qDebug() << info.isDir();  // 是否是目录
        qDebug() << info.isFile(); // 是否是文件
    }
}

void MainWindow::on_writeData()
{
    QString path = QFileDialog::getSaveFileName(this, "save", "../", "TXT(*.txt)");
    if(path.isEmpty() == false) {
        QFile file; //创建文件对象
        file.setFileName(path);//关联文件名字
        bool isOk = file.open(QIODevice::WriteOnly);//打开文件,只写方式
        if(isOk == true) {

            QString str = textEdit->toPlainText();//获取编辑区内容
             file.write(str.toUtf8()); //QString -> QByteArray
             file.write(str.toStdString().data());//QString -> c++ string -> char *
            //file.write(str.toLocal8Bit());//转换为本地平台编码
        }
        file.close();
    }
}

 mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGroupBox>
#include <QRadioButton>
#include <QStringList>
#include <QLineEdit>
#include <QGridLayout>
#include <QFormLayout>
#include <QTextCodec>
#include <QListWidget>
#include <QLabel>
#include <QStackedLayout>
#include <QTextEdit>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QDebug>
#include <QDateTime>
#include <QDataStream>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:

    void on_readData();
    void on_writeData();
private:
    QPushButton *buttonRead = new QPushButton();
    QPushButton *buttonWrite = new QPushButton();
    QTextEdit *textEdit = new QTextEdit();
};

#endif // MAINWINDOW_H

 运行结果:

 qfile读写16进制数据

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#define HexPrint(packet, len)\
do{\
    QByteArray data((const char*)packet, len); \
    QString hexString; \
    for (int i = 0; i < data.size(); i++) { \
        hexString += QString("%1 ").arg((quint8)data.at(i), 2, 16, QChar('0')); \
    } \
    qDebug() << hexString; \
}while(0);

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    writeDataToFile();
    readDataFromFile();
}

void MainWindow::writeDataToFile(void)
{
    QFile file("qfile_test.dat");
    if (!file.open(QIODevice::WriteOnly)) {
        // Handle error
        return;
    }

    uint8_t data_buf[32] ={
        0x55,0xAA,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
        0x66,0xBB,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00
    };
    QByteArray b_data((const char *)&data_buf,sizeof(data_buf));
    qint64 i64WriteBytes =  file.write(b_data);
    if( b_data.length() != i64WriteBytes ){
        qDebug()<<"write data len err";
     }

    file.close();
}

void MainWindow::readDataFromFile(void)
{
    QFile file("qfile_test.dat");
    if (!file.open(QIODevice::ReadOnly)) {
        // Handle error
        return;
    }
    QByteArray qbaData;
    file.seek(0);
    qbaData =  file.readAll();
    if( qbaData.length() != file.size() ){
       qDebug()<<"read data len err";
    }
    qDebug()<<"read data:";
    HexPrint(qbaData.data(),qbaData.size());
}

 QDataStream操作

读写16进制数据

读写quint16、和quint32类型的数据:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#include <QString>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    writeDataToFile();
    readDataFromFile();
}

void MainWindow::writeDataToFile(void)
{
    QFile file("test.dat");
    if (!file.open(QIODevice::WriteOnly)) {
        // Handle error
        return;
    }
    QDataStream out(&file);
    out.setByteOrder(QDataStream::LittleEndian); // 设置字节序为小端

    out << (quint16)0x1234;// 写入16进制数据
    out << (quint32)0xABCDEF12;
    QString qstr = "testString";
    out << qstr;

    file.close();
}

void MainWindow::readDataFromFile(void)
{
    QFile file("test.dat");
    if (!file.open(QIODevice::ReadOnly)) {
        // Handle error
        return;
    }
    QDataStream in(&file);
    in.setByteOrder(QDataStream::LittleEndian); // 设置字节序为小端

    quint16 value16;
    quint32 value32;
    QString qstr = "";
    //读的时候,按写的顺序取数据
    in >> value16; // 读取一个16位无符号整数
    in >> value32; // 读取一个32位无符号整数
    in >> qstr;

    file.close();
    qDebug("src:0x1234,read data: 0x%X\n",value16);// 使用读取的数据
    qDebug("src:0xABCDEF12,read data: 0x%X",value32);
    qDebug()<<"read qstr:"<<qstr;
}

写到文件的数据:

从文件读取数据放置对应的类型的变量,变量打印如下:

 读写uint8_t类型的数据buffer:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#define HexPrint(packet, len)\
do{\
    QByteArray data((const char*)packet, len); \
    QString hexString; \
    for (int i = 0; i < data.size(); i++) { \
        hexString += QString("%1 ").arg((quint8)data.at(i), 2, 16, QChar('0')); \
    } \
    qDebug() << hexString; \
}while(0);

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    writeDataToFile();
    readDataFromFile();
}

void MainWindow::writeDataToFile(void)
{
    QFile file("test.dat");
    if (!file.open(QIODevice::WriteOnly)) {
        // Handle error
        return;
    }
    QDataStream out(&file);//等价 QDataStream out;out.setDevice(&file);
    uint8_t data_buf[32] ={
        0x55,0xAA,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
        0x66,0xBB,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00
    };
    for(int i=0;i<sizeof(data_buf);i++){
        out << data_buf[i];
    }

    file.close();
}

void MainWindow::readDataFromFile(void)
{
    QFile file("test.dat");
    if (!file.open(QIODevice::ReadOnly)) {
        // Handle error
        return;
    }
    QDataStream in(&file);
    char data_buf[32];
    for(int i=0;i<sizeof(data_buf)/8;i++){
         in.readRawData(data_buf, 8);
         HexPrint(data_buf,8);
    }
}

 QTextStream

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#include <QString>
#include <QTextStream>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    writeDataToFile();
    readDataFromFile();
}

void MainWindow::writeDataToFile(void)
{
    QFile file("test.txt");
    if (!file.open(QIODevice::WriteOnly)) {
        // Handle error
        return;
    }

    QTextStream stream(&file);
    stream.setCodec("UTF-8");//指定编码
    stream << QString("QTextStream test") << 200;
    file.close();
}

void MainWindow::readDataFromFile(void)
{
    QFile file;
    file.setFileName("test.txt");
    if (!file.open(QIODevice::ReadOnly)) {
        // Handle error
        return;
    }
    QTextStream stream(&file);

    stream.setCodec("UTF-8");//指定编码

#if 0
    QString str;
    int a;
    stream >> str >> a;
    qDebug() << str.toUtf8().data()<< a;
#endif
    QString str = stream.readAll();
    qDebug() << str.toUtf8().data();
    file.close();
}

 运行打印结果:

QTextStream test200

QBuffer操作

与文件一样都是IO操作,方式也类似

1、文件需要QFile与一个实际文件相关联,缓冲区需要QBuffer与一片存储空间(QByteArray定义的)相关联

2、文件的打开需要QFile的对象来打开,缓冲区的打开需要QBuffer的对象来打开

3、写入和读出数据一般都需要QFile(或QBuffer)对象与QDataStream(或QTextStream)相关联 

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#include <QString>
#include <QTextStream>
#include <QBuffer>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    writeDataToFile();
    //readDataFromFile();
}

void MainWindow::writeDataToFile(void)
{
    QByteArray ba;
    QBuffer buffer(&ba);

    if(buffer.open(QIODevice::WriteOnly))//以只写二进制的形式打开
    {
        QDataStream out(&buffer);
        out << QString("QBuffer_Test");
        out << 520;
        out << 13.14;
        buffer.close();
    }

    if(buffer.open(QIODevice::ReadOnly))//读数据,也是使用上面定义的buf
     {
         QDataStream in(&buffer);
         QString str;
         int i_value;
         double d_value;
         in >> str;
         in >> i_value;
         in >> d_value;
         qDebug()<<"Qstring      = " << str;
         qDebug()<<"int value    = " <<i_value;
         qDebug()<<"double value = " <<d_value;

         buffer.close();
     }

}

 运行打印结果:

Qstring = "QBuffer_Test"

int value = 520

double value = 13.14

注意:如果重新定义一个函数读数据, 读写定义的Qbuffer不同了;那读出来的数据肯定不同;

QByteArray ba; QBuffer buffer(&ba);

void MainWindow::readDataFromFile(void)
{
/*
    QByteArray ba;
    QBuffer buffer(&ba);//要跟写数据的同一个变量,可以定义全局变量

   if(buffer.open(QIODevice::ReadOnly))
    {
        QDataStream in(&buffer);
        QString str;
        int i_value;
        double d_value;
        in >> str;
        //in >> i_value;
        //in >> d_value;
        qDebug()<<"Qstring   = " << str;
       // qDebug()<<"int value = " <<i_value;
       // qDebug()<<"double value = " <<d_value;

        buffer.close();
    }
*/
}

QDir操作

QDir类在很多实际应用场景中都能发挥作用,比如:

1.文件和目录管理:在应用程序中进行文件和目录的创建、复制、删除和重命名等操作,实现数据的管理和存储。

2.批量处理:当可以使用QDir类遍历目录中的所有文件,然后对每个文件进行相应操作。

3.目录比较:比较两个目录中的文件和子目录,查找差异或进行同步操作。

4.文件搜索:使用QDir类的entryList()函数配合正则表达式,可以实现对目录中符合特定规则的文件进行搜索。

5.日志管理:在记录日志的时候,可以使用QDir类创建和管理日志文件。

获取当前目录和目录创建

    QString currentPath = QDir::currentPath();// 获取当前目录
    qDebug()<<"currentPath :"<< currentPath;
  
	QDir dir;
	if (!dir.exists("new_dir")) {//如果没有这个文件夹
		 bool ok =  dir.mkpath("new_dir");//创建文件夹
	}
 //或者
    QDir dir1;
    if (dir1.mkdir("new_dir1")) {
        // 目录创建成功
    } else {
        // 目录已存在或创建失败
    }	
	

扫描文件夹指定后缀的文件,如下需要列出.isp结尾的文件:

void MainWindow::dir_test(QString path)
{
    QStringList filePathList;

    filePathList.clear();

    QString dirPath = "dir_test";
    QDirIterator it(dirPath, QStringList() << "*.isp", QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
    while(it.hasNext()){
        it.next();
        filePathList.append(it.fileInfo().absoluteFilePath());
    }

    qDebug()<<"fileList.size() ="<< filePathList.size();
    qDebug()<< filePathList;
    for(int i = 0; i< filePathList.size();++i){
        QString fileName = filePathList.at(i);
        qDebug()<<".isp file path :"<< fileName;
    }
}

子文件夹的文件也被递归列出来了

列出目录和筛选目录内容

    QDir dir("dir_test");

//仅获取目录下的文件列表,而不包含子目录,而忽略子目录的内容。
//  QStringList filesAndDirs = dir.entryList(QDir::Files);//使用QDir::Files过滤器
    QStringList filesAndDirs = dir.entryList();
    foreach (const QString& name, filesAndDirs) {
        qDebug()<<"file name: "<< name;
    }

过滤文件夹内容对比

QDir::Dirs:获取目录下的所有子目录。
QDir::AllEntries:获取目录下的所有文件和子目录(包括隐藏文件和隐藏目录)。
QDir::NoDotAndDotDot:排除特殊目录.和..。
QDir::Hidden:获取隐藏的文件和目录。

使用entryList()函数的重载版本,指定一个文件过滤器来选择只包含.ini扩展名的文件。以下是只打印出目录中的.ini文件: 

    QDir directory("/path/to/your/directory"); // 修改为你想遍历的目录路径

    QStringList iniFiles = directory.entryList(QStringList() << "*.ini", QDir::Files);
    foreach (const QString& iniFile, iniFiles) {
        qDebug() << "INI File:" << iniFile;
    }

 复制文件和目录

QFile::copy("sourceFile.txt", "destinationFile.txt");

QDir directory;
directory.rename("sourceDirectory", "destinationDirectory");

删除文件和目录

QFile::remove("fileToRemove.txt");

QDir directory;
directory.rmdir("directoryToRemove");

更改文件名

bool renameFile(const QString& directoryPath, const QString& oldFileName, const QString& newFileName) 
{
    QDir directory(directoryPath);
    if (directory.exists(oldFileName)) {
        if (directory.rename(oldFileName, newFileName)) {
            qDebug() << "File renaming successful!";
            return true;
        } else {
            qDebug() << "File renaming failed!";
            return false;
        }
    } else {
        qDebug() << "File not found!";
        return false;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值