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

文件操作概述

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:

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();//最后修改时间
    }
}

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:

cpp 复制代码
#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进制数据

cpp 复制代码
#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类型的数据:

cpp 复制代码
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
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;

    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;
    in >> value16; // 读取一个16位无符号整数
    in >> value32; // 读取一个32位无符号整数

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

写到文件的数据:

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

读写uint8_t类型的数据buffer:

cpp 复制代码
#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);
    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);
    }
}
相关推荐
捕鲸叉21 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer26 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq28 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
音徽编程2 小时前
Rust异步运行时框架tokio保姆级教程
开发语言·网络·rust
观音山保我别报错2 小时前
C语言扫雷小游戏
c语言·开发语言·算法
小屁孩大帅-杨一凡3 小时前
java后端请求想接收多个对象入参的数据
java·开发语言
m0_656974743 小时前
C#中的集合类及其使用
开发语言·c#