Qt 基础组件速学 文件篇File

学习目标: 文件操作

前置环境

运行环境:qt creator 4.12

学习内容和效果演示:

数据读写2种方式 不能同时混合使用

QTextStream处理文本数据,以Unicode文本的形式读写数据。

QDataStream处理二进制数据,以平台无关的二进制格式读写数据。

1.文件读写        QFile

太基础就不演示了,直接看下列代码吧

2.文件路径操作   QDir

两个小demo 一个递归读取文件夹大小

3.文件属性操作   QFileInfo

详细主要代码和运行测试

1.文件读写

#include <QCoreApplication>
#include<QFile>
#include<QIODevice>
#include<QTextStream>
#include<QDataStream>
#include<QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QFile f("./test.in");

    if(!f.open(QIODevice::WriteOnly ))
        return a.exec();
    /*
    数据读写2种方式 不能同时混合使用
    QTextStream处理文本数据,以Unicode文本的形式读写数据。
    QDataStream处理二进制数据,以平台无关的二进制格式读写数据。
    */
    QTextStream tstr(&f);

    //文件写入操作 << >>
    tstr<<"ip:127.0.0.1 ";
    tstr<<"port:28"<<"\n";
    f.write("ip:127.0.0.2 ",qstrlen("ip:127.0.0.2 ")); //使用write性能更高,更接近底层。
    f.write("port:28 \t ",qstrlen("port:28 \t "));

    tstr<<"ip:127.0.0.3 ";
    tstr<<"port:28";
    f.flush();
    f.close();

    //文件读取
    if(!f.open(QIODevice::ReadOnly | QIODevice::Text ))
        return a.exec();

    tstr.setDevice(&f);
    QString line =tstr.readLine();

    while(!line.isNull()){
        qDebug()<<line;
        line=tstr.readLine();

    }

    f.close();

    //下面演示关于二进制读写取
    if(!f.open(QIODevice::WriteOnly )) return a.exec();
    QDataStream bstr(&f);
    bstr<<QString("这是数据流qwhe123 =/*-")<<1234<<true;
    f.flush();
    f.close();


    if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) return a.exec();
    QString stringValue;
    int intValue;
    bool boolValue;

    bstr >> stringValue >> intValue >> boolValue;
    qDebug() << "Read data:";
    qDebug() << "Integer value:" << intValue;
    qDebug() << "Boolean value:" << boolValue;
    qDebug() << "String value:" << stringValue;
    f.flush();
    f.close();


    return a.exec();
}

2.文件路径操作

功能:读取当前文件夹的所有文件大小

#include <QCoreApplication>
//QDir 用于操作路径名、访问有关路径和文件的信息以及操作底层文件系统。它也可以用来访问Qt的.
#include<QDir>
#include<qdebug.h>
/*
QDir::separator()是Qt中的一个静态函数,它返回当前操作系统使用的目录分隔符。
在不同的操作系统上,目录路径的分隔符是不同的:
Windows 系统使用反斜杠 \ 作为分隔符。
Unix 系统和 macOS 使用正斜杠 / 作为分隔符。
*/
std::tuple<char, qint64> GetDirType(qint64 qsize){
    char utype='B';
    qint64 currentdirsize=qsize;

    if(currentdirsize>1024)
    {
        currentdirsize=currentdirsize/1024;
        utype='K';
        if(currentdirsize>1024)
        {
            currentdirsize=currentdirsize/1024;
            utype='M';
            if(currentdirsize>1024)
            {
                currentdirsize=currentdirsize/1024;
                utype='G';
                if(currentdirsize>1024)
                {
                    currentdirsize=currentdirsize/1024;
                    utype='T';
                }
            }
        }
    }

     return std::make_tuple(utype, currentdirsize);
}
std::tuple<char, qint64> GetDirFileSize(const QString &path){
    QDir dir(path);
    qint64 qsize=0;
    //获取path目录下的文件
    foreach(QFileInfo info,dir.entryInfoList(QDir::Files)){
        qsize+=info.size();
    }
    return GetDirType(qsize);
}

qint64  GetDirFileSizeSet(const QString &path){
    QDir dir(path);
    qint64 qsize=0;
    //获取path目录下的文件
    foreach(QFileInfo info,dir.entryInfoList(QDir::Files)){
        qsize+=info.size();
    }
    //用于递归计算目录及其子目录下所有文件的总大小 QDir::Dirs 表示只包含目录, QDir::NoDotAndDotDot 表示排除 "." 和 ".." 这两个特殊目录。
    foreach(QString dpath,dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)){
        //qpath+QDir::separator()+sDir拼接了当前目录路径和子目录名称,形成了子目录的完整路径。

        qsize+= GetDirFileSizeSet(path+QDir::separator()+dpath);
    }

    return qsize;
}
std::tuple<char, qint64>  GetDirFileSizeF(const QString &path){
    qint64 qsize = GetDirFileSizeSet(path);

     return GetDirType(qsize);;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString str= QDir::currentPath();
    auto file = GetDirFileSize(str);
    qDebug()<<str<<"文件总大小:"<<std::get<1>(file)<<std::get<0>(file);
    auto f = GetDirFileSizeF(str);
    qDebug()<<str<<"文件集合总大小:"<<std::get<1>(f)<<std::get<0>(f);

    return a.exec();
}

2.1 功能:文件夹视为文件夹图标,文件视为文件图标

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    setGeometry(200,200,500,300);

    le=new QLineEdit("/");
    ls=new QListWidget(this);
    v= new QVBoxLayout(this);
    v->addWidget(le);
    v->addWidget(ls);

    QString root ="/";
    QStringList rule("*");
    QDir dir(root);

    QFileInfoList list= dir.entryInfoList(rule);
    display(list);
    //当用户按下 Enter 键或 Return 键时该信号会被触发。
    connect(le,SIGNAL(returnPressed()),this,SLOT(displayPath(DIR)));
   connect(ls,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(displayItem(QListWidgetItem*)));
}

// 显示目录和文件所对应图标
void Dialog::display(QFileInfoList &list){
    ls->clear();

    for(int i=0;i<list.size();i++){
        QFileInfo file=list.at(i);

        QIcon ico;

        if(file.isDir()){
            ico.addFile(":/new/prefix1/dir.jpg");
        }
        else if(file.isFile()){
            ico.addFile(":/new/prefix1/file.jpg");
        }

        QListWidgetItem* item=new QListWidgetItem(ico,file.fileName());
        ls->addItem(item);
    }
}


//修改列表控件
void Dialog::displayPath(QDir dir){
    QStringList rule("*");
    //QDir::AllEntries 表示包括文件和目录。 QDir::DirsFirst表示首先返回目录项,然后是文件项。
    QFileInfoList list =dir.entryInfoList(rule,QDir::AllEntries,QDir::DirsFirst);
    display(list);

}
//修改路径
void Dialog::displayItem(QListWidgetItem *item){
    QDir dir(le->text()); //记录当前

    dir.cd(item->text());//cd 双击的
    le->setText(dir.absolutePath());
    displayPath(dir);
}

3.文件属性操作

功能:选择一个文件获取文件详细信息

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    this->setGeometry(200,200,200,150);
    grid=new QGridLayout(this);

    QLabel* pathk=new QLabel("文件路径名称: ");
    QLineEdit* pathv=new QLineEdit();
    QPushButton* pathPb=new QPushButton("选择文件");
    QHBoxLayout* one = new QHBoxLayout(this);
    one->addWidget(pathk);
    one->addWidget(pathv);
    one->addWidget(pathPb);
    grid->addLayout(one,0,0);

    QLabel* capacityk=new QLabel("容量大小: ");
    QLineEdit* capacityv=new QLineEdit();
    QHBoxLayout* two = new QHBoxLayout(this);
    two->addWidget(capacityk);
    two->addWidget(capacityv);
    grid->addLayout(two,1,0);

    QLabel* createk=new QLabel("文件创建时间: ");
    QLineEdit* createv=new QLineEdit();
    QHBoxLayout* three = new QHBoxLayout(this);
    three->addWidget(createk);
    three->addWidget(createv);
    grid->addLayout(three,2,0);

    QLabel* fin_updatek=new QLabel("最后修改时间: ");
    QLineEdit* fin_updatev=new QLineEdit();
    QHBoxLayout* four = new QHBoxLayout(this);
    four->addWidget(fin_updatek);
    four->addWidget(fin_updatev);
    grid->addLayout(four,3,0);

    QLabel* fin_selectk=new QLabel("最后访问时间: ");
    QLineEdit* fin_selectv=new QLineEdit();
    QHBoxLayout* five = new QHBoxLayout(this);
    five->addWidget(fin_selectk);
    five->addWidget(fin_selectv);
    grid->addLayout(four,4,0);

    QLabel* file=new QLabel("文件属性: ");
    grid->addWidget(file,5,0);

    QCheckBox* filek=new QCheckBox;
    QLabel* filev=new QLabel("文件");
    QCheckBox* hidek=new QCheckBox;
    QLabel* hidev=new QLabel("隐藏属性");
    QCheckBox* readk=new QCheckBox;
    QLabel* readv=new QLabel("只读权限");
    QCheckBox* writek=new QCheckBox;
    QLabel* writev=new QLabel("只写权限");
    QCheckBox* execk=new QCheckBox;
    QLabel* execv=new QLabel("执行权限");

    QHBoxLayout* six = new QHBoxLayout(this);
    six->addWidget(filek);
    six->addWidget(filev);

    six->addWidget(hidek);
    six->addWidget(hidev);
    six->addWidget(readk);
    six->addWidget(readv);
    six->addWidget(writek);
    six->addWidget(writev);
    six->addWidget(execk);
    six->addWidget(execv);

    grid->addLayout(six,6,0);

    QPushButton* getFileInfo=new QPushButton("获取文件属性详细信息",this);
    grid->addWidget(getFileInfo,7,0);

    QObject::connect(pathPb,&QPushButton::clicked,this,[this,pathv](){
        QString filepath = QFileDialog::getOpenFileName(this,tr("打开文件"),"/",tr("Files(*)"));
        pathv->setText(filepath);

    });

    QObject::connect(getFileInfo,&QPushButton::clicked,this,[=](){
        QString str =pathv->text();
        QFileInfo file(str);
        capacityv->setText(QString::number(file.size()));
        createv->setText(file.birthTime().toString());
        fin_updatev->setText(file.lastModified().toString());
        fin_selectv->setText(file.lastRead().toString());
        filek->setCheckState(file.isFile()?Qt::Checked:Qt::Unchecked);
        hidek->setCheckState(file.isHidden()?Qt::Checked:Qt::Unchecked);
        readk->setCheckState(file.isReadable()?Qt::Checked:Qt::Unchecked);
        writek->setCheckState(file.isWritable()?Qt::Checked:Qt::Unchecked);
        execk->setCheckState(file.isExecutable()?Qt::Checked:Qt::Unchecked);
    });

    setLayout(grid);
}

Dialog::~Dialog()
{
}

总结:

文件读写:文本或者二进制,还有一种使用POSIX API 文件读写,原始读写方法更接近底层,性能也就更高。

文件路径:QDir类,其中重要函数是 entryInfoList 此函数用于获取文件,并可过滤文件。

文件属性:QFileinfo 提供一些列的文件属性函数。

最后附上源代码链接
对您有帮助的话,帮忙点个star

23-QDir · jbjnb/Qt demo - 码云 - 开源中国 (gitee.com)

24-dirproj · jbjnb/Qt demo - 码云 - 开源中国 (gitee.com)

25-QFileinfo · jbjnb/Qt demo - 码云 - 开源中国 (gitee.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值