Qt文件操作 day3

Qt文件操作 day3

I/O设备

  • Qt中的IO设备统一了文件与外部的操作方式,Qt中文件被当作一种特殊的外部设备,文件操作与外部设备操作相同
  • QIODevice为支持读写数据块(如QFile、QBuffer和QTcpSocket)的设备提供了通用实现和抽象接口。QIODevice是抽象的,不能被实例化,但是通常使用它定义的接口来提供与设备无关的I/O特性。

I/O设备的类型

  • 顺序存取设备:只能从头开始顺序读写数据,不能指定数据的读写位置
  • 随机存取设备:可以定位到任意位置进行数据的读写

打开模式

文件打开需要指定模式,模式是一个枚举类型QIODeviceBase::OpenModeFlag,打开模式与QIODevice::open()一起使用,描述设备的打开模式。它也由QIODevice::openMode()返回。

方法描述
QIODeviceBase::NotOpen设备未打开
QIODeviceBase::ReadOnly只读设备
QIODeviceBase::WriteOnly只写打开的设备,注意,对于文件系统子类(例如QFile),这种模式意味着截断(清空文件),除非与ReadOnly、Append或NewOnly结合使用。
QIODeviceBase::ReadWrite读写设备
QIODeviceBase::Append以追加模式打开设备,这样所有数据都被写入文件的末尾。
QIODeviceBase::Truncate如果可以,则打开时会清空设备
QIODeviceBase::Text读取时,行尾终止符被翻译为’\n’。在编写时,行尾终止符被转换为本地编码,例如Win32中的’\r\n’。
QIODeviceBase::Unbuffered设备中的任何缓冲区都被绕过。
QIODeviceBase::NewOnly如果要打开的文件已经存在,则失败。仅在文件不存在时创建并打开该文件。操作系统保证您是唯一创建和打开文件的人。注意,这种模式意味着WriteOnly,并且允许将其与ReadWrite结合使用。此标志目前只影响QFile。
QIODeviceBase::ExistingOnly如果要打开的文件不存在,则失败。此标志必须与ReadOnly、WriteOnly或ReadWrite一起指定。注意,单独将此标志与ReadOnly一起使用是多余的,因为当文件不存在时,ReadOnly已经失败了。此标志目前只影响QFile。

QFile文件读写

  • 创建QFile对象,通过构造函数或者setFilename()设置文件名,然后使用open函数以指定的打开模式打开文件。
    • 如果打开失败,可以通过errorString()获取失败的原因。
#include <QApplication>
#include <QWidget>
#include <QFile>

void openFile()
{
    //打开文件,如果不存在创建一个文件
    QFile file("xiaogua.txt");//相对路径
    if (!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "open:" << file.fileName() << "failed:" << file.errorString();
    }
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    openFile();
    return a.exec();
}
  • 如果要改创建位置,可以在CMAkeLists里面设置路径
# 生成在CMAkeLists同级目录的bin目录下
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
  • 然后把启动项目换成当前项目运行就会生成在bin目录下
    在这里插入图片描述

写入数据

  • 文件打开成功后,使用write()来写入数据
#include <QApplication>
#include <QWidget>
#include <QFile>

void openFile()
{
    //打开文件,如果不存在创建一个文件
    QFile file("xiaogua.txt");
    if (!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "open:" << file.fileName() << "failed:" << file.errorString();
    }

    //写入数据
    file.write("xiaogua hello world!");
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    openFile();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述

读取文件

  • vs只认识Ansi编码,在vs中下载一个插件force utf8,这个插件可以强制保存为utf-8,下载这个插件后,以后也能输出中文日志了
    在这里插入图片描述
  • 文件打开成功后,使用read()来读取指定长度的数据,使用readLine()来读取一行,使用readAll读取所有数据。
#include <QApplication>
#include <QWidget>
#include <QFile>

void openFile()
{
    //打开文件,如果不存在创建一个文件
    QFile file("xiaogua.txt");
    if (!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "open:" << file.fileName() << "failed:" << file.errorString();
    }

    //写入数据
    file.write("xiaogua hello world\n");
    file.write("小瓜");

}

void redFile()
{
    QFile file("xiaogua.txt");
    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "open:" << file.fileName() << "failed:" << file.errorString();
    }

    //读取数据
    auto Data = file.read(30);
    qDebug() << QString::fromUtf8(Data);

    //设置文件指针位置
    file.seek(0);

    //读取一行
    qDebug() << file.readLine();

    //设置文件指针位置
    file.seek(0);

    //读取所有内容
    qDebug() <<QString::fromUtf8(file.readAll());
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    openFile();
    redFile();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述

Qt流操作Stream

  • 在上面的读写文件中,我们发现操作还是太过复杂,为了简化文本文件和数据文件的读写操作,QT提供了QTextStream和QDataStream辅助类。QTextStream可将写入的数据全部转换为可读文本,QDataStream可将写入的数据根据类型转换为二进制数据
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
void Text_file()
{
    QFile file("xiaogua.txt");
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);//把文件和文本建立关联,用流去操作文件
        QString str;
        stream >> str;
        qDebug() << str;
    }
    else
    {
        qDebug() <<file.errorString();
    }
    //文本流 #include <QDataStream>
    {
        QString str;
        QTextStream stream(&str);
        stream << "小瓜" << " " << 21;
        qDebug() << str;
    }
    //二进制流 #include <QDataStream>
    {
        //序列化数据
        int age = 21;
        QString name = "xiaogua";

        QByteArray data;
        QDataStream stream(&data,QIODevice::ReadWrite);
        stream << age << name;
        qDebug() << data;
    }
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    Text_file();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述

配置文件

QSettings

  • 用户通常希望应用程序在会话中记住它的设置(窗口大小和位置,选项等)。 这些信息通常存储在Windows上的系统注册表中(HKEY_CURRENT_USERSoftware/MySoft ),以及macOS和iOS上的属性列表文件中。 在Unix系统上,在缺乏标准的情况下,许多应用程序(包括KDE应用程序)使用INI文本文件。

  • QSettings是对这些技术的抽象,使您能够以可移植的方式保存和恢复应用程序设置。 它还支持自定义存储格式。

  • QSettings的API基于QVariant,因此我们可以保存很多的类型,如QString、QRect和QImage。

  • 如果您所需要的只是一个非持久的基于内存的结构,那么可以考虑使用QMap<QString,QVariant>替代。

QSettings存储设置。 每个设置由一对(key,value)键值对(key为QStirng类型,value为QVariant)组成。 要写入设置,可以使用setValue()。

#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>

void Setting()
{
    //读入配置
    QSettings setting("XiaoGua", qApp->applicationName());
    auto name = setting.value("name").toString();
    auto version= setting.value("version").toFloat();

    qDebug() << name << " " << version;
    //写入配置
    {
        QSettings setting("XiaoGua", qApp->applicationName());
        setting.setValue("name", "dagua");
        setting.setValue("version", 1.0);
    }
}

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    Setting();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述

    在这里插入图片描述

  • 每次写QSettings setting(“XiaoGua”, qApp->applicationName());很麻烦,其实QSettings会自动调用QApplication对象里面的organizationName与applicationName,那我们可以直接设置

#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>

void Setting()
{
    //读入配置
    //QSettings setting("XiaoGua", qApp->applicationName());
    QSettings setting;
    auto name = setting.value("name").toString();
    auto version= setting.value("version").toFloat();

    //qDebug() << name << " " << version;
    //写入配置
    {
        //QSettings setting("XiaoGua", qApp->applicationName());
        QSettings setting;
        setting.setValue("name", "dagua");
        setting.setValue("version", 1.0);
    }
}

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    qDebug() << a.organizationName() << a.applicationName();
    Setting();
    return a.exec();
}
配置文件格式
  • 在windows下,默认为写入注册表,写入.ini文件并保存到exe所在目录
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>

void Setting()
{
    //读入配置
    //QSettings setting("XiaoGua", qApp->applicationName());
    QSettings setting;
    auto name = setting.value("name").toString();
    auto version= setting.value("version").toFloat();

    //qDebug() << name << " " << version;
    //写入配置
    {
        //QSettings setting("XiaoGua", qApp->applicationName());
        QSettings setting;
        setting.setValue("name", "dagua");
        setting.setValue("version", 1.0);
    }

    //写入ini文件
    {
        QSettings setting("xiaogua.ini", QSettings::Format::IniFormat);
        setting.setValue("host", "202.101.21.8");
        setting.setValue("por", 8080);

    }
}

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    qDebug() << a.organizationName() << a.applicationName();
    Setting();
    return a.exec();
}
  • 此时就会多出一个xiaogua.ini,我们编写ini数据,这种格式就是一个组一个等式一个键值对
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>

void Setting()
{
    //读入配置
    //QSettings setting("XiaoGua", qApp->applicationName());
    QSettings setting;
    auto name = setting.value("name").toString();
    auto version= setting.value("version").toFloat();

    //qDebug() << name << " " << version;
    //写入配置
    {
        //QSettings setting("XiaoGua", qApp->applicationName());
        QSettings setting;
        setting.setValue("name", "dagua");
        setting.setValue("version", 1.0);
    }

    //写入ini文件
    {
        QSettings setting("xiaogua.ini", QSettings::Format::IniFormat);
        setting.setValue("host", "202.101.21.8");
        setting.setValue("por", 8080);

        //设置组
        setting.beginGroup("admin");
        setting.setValue("username", "admin");
        setting.setValue("pssswrod", "admin");
        setting.endGroup();
    }
}

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    qDebug() << a.organizationName() << a.applicationName();
    Setting();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述
  • 读取ini文件
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>

void Setting()
{
    //读入配置
    //QSettings setting("XiaoGua", qApp->applicationName());
    QSettings setting;
    auto name = setting.value("name").toString();
    auto version= setting.value("version").toFloat();

    //qDebug() << name << " " << version;
    //写入配置
    {
        //QSettings setting("XiaoGua", qApp->applicationName());
        QSettings setting;
        setting.setValue("name", "dagua");
        setting.setValue("version", 1.0);
    }

    //写入ini文件
    {
        QSettings setting("xiaogua.ini", QSettings::Format::IniFormat);
        setting.setValue("host", "202.101.21.8");
        setting.setValue("por", 8080);

        //设置组
        setting.beginGroup("admin");
        setting.setValue("username", "admin");
        setting.setValue("password", "admin");
        setting.endGroup();
    }
    //读取ini文件
    {
        QSettings setting("xiaogua.ini", QSettings::Format::IniFormat);
        qDebug() << setting.value("host").toString();
        setting.beginGroup("admin");
        qDebug() << setting.value("password").toString();
        //另一种方式,当读取的值不存在的时候会返回输入的
        qDebug() << setting.value("passwrod", "12345").toString();
        setting.endGroup();
    }
}

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    qDebug() << a.organizationName() << a.applicationName();
    Setting();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述
  • 设置数组与读取数组
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>

void Setting()
{
    //读入配置
    //QSettings setting("XiaoGua", qApp->applicationName());
    QSettings setting;
    auto name = setting.value("name").toString();
    auto version= setting.value("version").toFloat();

    //qDebug() << name << " " << version;
    //写入配置
    {
        //QSettings setting("XiaoGua", qApp->applicationName());
        QSettings setting;
        setting.setValue("name", "dagua");
        setting.setValue("version", 1.0);
    }

    //写入ini文件
    {
        QSettings setting("xiaogua.ini", QSettings::Format::IniFormat);
        setting.setValue("host", "202.101.21.8");
        setting.setValue("por", 8080);

        //设置组
        setting.beginGroup("admin");
        setting.setValue("username", "admin");
        setting.setValue("password", "admin");
        setting.endGroup();

        //设置数组
        setting.beginWriteArray("ages");
        for (size_t i = 0; i < 5; i++)
        {
            setting.setArrayIndex(i);
            //格式化一下
            setting.setValue(QString("ages_%1").arg(i), 21+i);
        }
        setting.endArray();
    }
    //读取ini文件
    {
        QSettings setting("xiaogua.ini", QSettings::Format::IniFormat);
        qDebug() << setting.value("host").toString();
        setting.beginGroup("admin");
        qDebug() << setting.value("password").toString();
        //另一种方式,当读取的值不存在的时候会返回输入的
        qDebug() << setting.value("passwrod", "12345").toString();
        setting.endGroup();

        //读取数组
        //获取数组大小
        qsizetype size = setting.beginReadArray("ages");
        for (size_t i = 0; i < size; i++)
        {
            setting.setArrayIndex(i);
            //读取时要和名字保持一致
            qDebug()<<setting.value(QString("ages_%1").arg(i)).toInt();
        }
    }

}

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    qDebug() << a.organizationName() << a.applicationName();
    Setting();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述在这里插入图片描述

QJsonDocument

  • QJsonDocument是一个包装完整JSON文档的类,它可以从基于UTF-8编码的文本表示中读取和写入该文档。可以使用QJsonDocument::fromJson()将JSON文档从基于文本的表示形式转换为QJsonDocument。toJson()将其转换回文本。解析器能非常快速且有效的将JSON转换为Qt使用的二进制表示形式。

  • isNull()可以查询已解析文档的有效性。

  • 可以使用isArray()和isObject()查询文档是否包含数组或对象。可以使用array()或object()检索文档中包含的数组或对象,然后读取或操作。

  • 什么是json,json是一种标记语言

类型:值类型 空类型 字符串类型 布尔类型 数组类型 对象类型
语法:由键值对构成 key:value
对象
{
	"name":"xiaogua", # 键必须由双引号包裹
	"age"21,		  # 每对键值对之间用逗号分隔
	"tel":null,
	"family":["爸爸","妈妈"]
}
数组
[
	"爸爸",
	"妈妈"
]
  • 解析简单对象
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>

//打开json文件
QJsonDocument parseJson()
{
    QFile file("./xiaogua.json");
    //判断打开是否成功
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << file.errorString();
        return QJsonDocument();
    }
    //json的erroString是需要定义一个指针进行传输的
    QJsonParseError error;
    QJsonDocument js = QJsonDocument::fromJson(file.readAll(),&error);
    if (error.error!=QJsonParseError::NoError)
    {
        qDebug() << error.errorString();
        return QJsonDocument();
    }
    return js;
}
void test_json()
{
    //接收一下
    QJsonDocument jdoc = parseJson();
    {//解析简单对象
        qDebug() << jdoc["name"].toString() << jdoc["age"].toInt();
    }
    
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    test_json();

    return a.exec();
}
  • 运行结果
    在这里插入图片描述
  • 解析简单数组
  • 数据如下
    在这里插入图片描述
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
//打开json文件
QJsonDocument parseJson()
{
    QFile file("./xiaogua.json");
    //判断打开是否成功
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << file.errorString();
        return QJsonDocument();
    }
    //json的erroString是需要定义一个指针进行传输的
    QJsonParseError error;
    QJsonDocument js = QJsonDocument::fromJson(file.readAll(),&error);
    if (error.error!=QJsonParseError::NoError)
    {
        qDebug() << error.errorString();
        return QJsonDocument();
    }
    return js;
}
void test_json()
{
    //接收一下
    QJsonDocument jdoc = parseJson();
    {//解析简单数组
        for (size_t i = 0; i < 9; i++)
        {
            QJsonValue v = jdoc[i];
            //在json里面数字就是double
            if (v.isDouble())
            {
                qDebug() << v.toInt();
            }
            //判断是否是字符串
            else if (v.isString())
            {
                qDebug() << v.toString();
            }
            //判断是否是对象
            //方法一
            /*
            else if(v.isObject())
            {
                qDebug() << v["name"].toString()<<v["age"].toInt();
            }
            */
            //方法二 添加一个json对象的头文件#include <QJsonObject>
            else if (v.isObject())
            {
                QJsonObject obj = v.toObject();
                qDebug() << obj.value("name").toString() << obj.value("age").toInt();
            }
        }
    }
    
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    test_json();

    return a.exec();
}
  • 运行结果
    在这里插入图片描述
解析复杂全国省市区json文件
  • 解析结构:一个根数组,里面一个省级对象,对象城市里面包含一个数组,数组里面又包含对象,对象区域级里面包含数组分区
    在这里插入图片描述
  • 解题思路:根对象是个数组首先获取整个根数组的大小,遍历数组,挨个判断元素是对象还是数组,依次输出省市区
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
//打开json文件
QJsonDocument parseJson()
{
    QFile file("./city.json");
    //判断打开是否成功
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << file.errorString();
        return QJsonDocument();
    }
    //json的erroString是需要定义一个指针进行传输的
    QJsonParseError error;
    QJsonDocument js = QJsonDocument::fromJson(file.readAll(),&error);
    if (error.error!=QJsonParseError::NoError)
    {
        qDebug() << error.errorString();
        return QJsonDocument();
    }
    return js;
}
void test_city()
{
    //接收一下
    QJsonDocument jdoc = parseJson();
    //包含头文件#include <QJsonArray>
    //获取json根数组大小
    QJsonArray ProvinceArray = jdoc.array();
    for (size_t i = 0; i < ProvinceArray.size(); i++)
    {   
        //获取对象
        auto provinceObj = ProvinceArray[i].toObject();
        //先拿出name输出
        qDebug() <<"----"<< provinceObj["name"].toString();
        
        //然后再拿到省对象里面的city数组
        auto cityArray = provinceObj["city"].toArray();
        //继续遍历city数组里面的对象元素,首先先输出city里面的name
        for (size_t j= 0; j < cityArray.size(); j++)
        {
            //获取city里面的对象
            auto cityObj = cityArray[j].toObject();
            //先输出里面的name
            qDebug() << "-------" << cityObj["name"].toString();

            //然后再拿到city数组对象里面的area数组
            auto districtArray = cityObj["area"].toArray();
            for (size_t z = 0; z < districtArray.size(); z++)
            {
                //最后输出city对象area数组的区
                qDebug() <<"-------------" << districtArray[z].toString();
            }
        }
    }
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    test_city();
    return a.exec();
}
  • 运行结果
    在这里插入图片描述

目录/路径

QDir

  • QDir功能:
    • 目录分隔符统一使用’/’
    • 计算目录大小
    • 能对目录进行任意操作(创建,删除,重命名)
    bool mkdir(const QString &dirName) const
    bool mkpath(const QString &dirPath) const
        
    bool rmdir(const QString &dirName) const	//删除子目录(必须为空才能删除)
    bool rmpath(const QString &dirPath) const	//删除路径(必须为空才能删除)
    bool remove(const QString &fileName)		//删除指定文件
    bool removeRecursively()					//删除目录,包括它的所有内容 
    
    bool rename(const QString &oldName, const QString &newName)	//重命名
    
    • 获取常用路径
    //返回应用程序当前目录的绝对路径
    QDir current()
    QString currentPath()
    
    //返回用户主目录  C:/Users/Maye
    QDir home()
    QString homePath()
    
    //返回系统的临时目录。   
    QDir temp()
    QString tempPath()
    
    //返回根目录列表 C:/  D:/ ...
    QFileInfoList drives()
    
    • 能获取指定目录中的所有文件和文件夹
QFileInfoList entryInfoList(const QStringList &nameFilters, QDir::Filters filters = NoFilter, QDir::SortFlags sort = NoSort) const
QFileInfoList entryInfoList(QDir::Filters filters = NoFilter, QDir::SortFlags sort = NoSort) const
QStringList entryList(const QStringList &nameFilters, QDir::Filters filters = NoFilter, QDir::SortFlags sort = NoSort) const
QStringList entryList(QDir::Filters filters = NoFilter, QDir::SortFlags sort = NoSort) const
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
void test_dir()
{
    //创建目录对象 头文件#include <QDir>
    QDir dir("../bin");
    //判断目录是否存在
    if(!dir.exists())
    {
        qDebug() << "目录不存在";
        return;
    }
    //获取目录项列表
    QStringList dir_list = dir.entryList();
    for (auto& v : dir_list)
    {
        qDebug() << v;
    }
    //获取项目文件信息列表
    QFileInfoList info_list=dir.entryInfoList();
    for (auto& info : info_list)
    {
        qDebug() <<(qreal)info.size()/1024/1024<<"MB" << info.fileName() << info.absoluteFilePath();
    }

    //创建目录
    dir.mkdir("xiaogua");
    //将dir的目录指定成目标名字,如果新目录存在则返回true,否则不进行目标操作
    //就是进入xiaogua文件
    dir.cd("xiaogua");
    dir.mkpath("aa//bb//cc");
    //删除aa bb cc
    dir.rmpath("aa//bb//cc");
    

}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    test_dir();

    return a.exec();
}
  • 运行结果
    在这里插入图片描述

QDirIterator

  • 它类似于QDir::entryList()和QDir::entryInfoList(),但由于它一次列出一个条目而不是一次列出所有条目,因此它的可伸缩性更好,更适合大型目录。它还支持递归列出目录内容,并遵循符号链接。与QDir::entryList()不同,QDirIterator不支持排序。
  • 遍历项目目录与查找C盘中的C.png
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QDirIterator>
#include <QDebug>
void test_DirIterator()
{
    //遍历项目目录  头文件#include <QDirIterator> 
    QDirIterator i("../",QDirIterator::IteratorFlag::Subdirectories);
    while (i.hasNext())
    {
        qDebug() << i.next();
    }
    
    //找到C盘中的C.png
    QDirIterator it("C:", QDirIterator::IteratorFlag::Subdirectories);
    while (it.hasNext())
    {
        QString str = it.next();
        if (str.endsWith("C.png"))
        {
            qDebug() << str;
        }
    }    
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    test_DirIterator();

    return 0;//a.exec();
}
  • 运行结果
    在这里插入图片描述
  • 查找所有盘符的C.png
  • 解析:
    • foreach 是 Qt 框架提供的一个宏,用于在容器(如 QList、QVector、QSet 等)中进行迭代。它是 Qt 为了方便开发者进行容器遍历而提供的一种语法。
      在上述代码中,foreach 循环用于遍历 drives 这个包含了系统上所有盘符信息的列表。这里的 drives 是一个 QFileInfoList 类型的列表,其中包含了系统上所有可用盘符的信息。
      const QFileInfo& drive 这一部分是循环体中每次迭代时所获取的变量。它的含义是将 drives 列表中的每个元素取出,这些元素是 QFileInfo 类型的对象,表示一个盘符的信息。const 修饰符表示这是一个只读的引用,不会对 drive 对象进行修改。
      综合起来,foreach (const QFileInfo& drive, drives) 的意思是:对于 drives 中的每一个 QFileInfo 对象,将其以 drive 这个名字引用,然后在循环体中可以使用 drive 来访问该盘符的信息。这样的语法让遍历容器变得更加简洁和易读,同时隐藏了底层的迭代器实现细节
    • QStringList() << targetFileName 这个表达式是将一个字符串targetFileName添加到一个QStringList列表中的一种方式。在上下文中,它的目的是创建一个只包含一个元素的字符串列表,其中这个元素就是 targetFileName 变量的值。
      • QStringList():这是一个空的QStringList列表的构造函数调用,用于创建一个空的字符串列表。

      • <<:这是列表类的操作符重载,它用于将一个元素附加到列表的末尾。

      • targetFileName:这是一个 QString 类型的变量,其中存储了要添加到列表中的字符串。

      • 所以这里也有改成这样,默认列表参数方式

	    QDirIterator it(drive.absoluteFilePath(), { targetFileName }, QDir::Files, QDirIterator::Subdirectories);
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QDirIterator>
#include <QDebug>
void test_DirIterator()
{
    //获取所有盘符列表
    auto drives = QDir::drives();
    QString targetFileName = "C.png"; // 要查找的文件名
    foreach(const QFileInfo& drive, drives)
    {
        QDirIterator it(drive.absoluteFilePath(), QStringList()<<targetFileName, QDir::Files, QDirIterator::Subdirectories);
        while (it.hasNext())
        {
            QString str = it.next();
            qDebug() << "Found file in drive:" << str;

        }
    }
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    test_DirIterator();

    return 0;//a.exec();
}
  • 运行结果
    在这里插入图片描述

QStandardPaths

简介

QStandardPaths类提供了访问标准路径的方法。 所谓系统标准路径指的是本地文件系统中,用户的特定目录或系统的配置目录。比如在Windows系统中的“我的文档”,“视频”,“图片”等目录位置。
对于一个大型项目,系统的标准目录是保存数据,配置信息的一个非常有用的地方。
对于系统标准目录,我们可以认定它是必然存在的(即使不存在,也可自动创建),但是不同的操作系统,可能有不一样的系统标准目录。例如“我的文档”目录位置

  • Windows:C:/Users/ u s e r n a m e username username/Documents
  • MacOs :~/Documents
  • Linux : ~/Documents
  • Android :/Documents,//Documents
  • IOS :/Documents

如果想要做跨平台的系统,像这些路径,你都得想办法获取,这只是一个我的文档,如果再加上“下载”,“图片”等标准路径,想想是不是都很麻烦。

然而,Qt却给我们提供了非常方便的类来获取这些标准目录路径,它就是马上要学习的QStandardPaths类。所有函数均为静态函数

静态共有函数
  • 返回给定位置类型的本地化显示名称,如果找不到相关位置,则返回空QString。
[static] QString displayName(QStandardPaths::StandardLocation type)
  • 在指定路径中查找名为executableName的可执行文件,如果路径为空则查找系统路径。
[static] QString findExecutable(const QString &executableName, const QStringList &paths = QStringList())
  • 在type的标准位置中查找名为fileName的文件或目录。
[static] QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options = LocateFile)
  • 根据文件名fileName在type的标准位置查找所有文件或目录。
[static] QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options = LocateFile)
  • 如果testMode为true,这将在QStandardPaths中启用一个特殊的“测试模式”,它将更改可写的位置以指向测试目录。 这将阻止自动测试读取或写入当前用户的配置。
[static] void setTestModeEnabled(bool testMode)
  • 返回该类型文件所属的所有目录。
[static] QStringList standardLocations(QStandardPaths::StandardLocation type)
  • 返回写入类型为文件的目录,如果无法确定位置,则返回空字符串。
[static] QString writableLocation(QStandardPaths::StandardLocation type)
  • 获取标准路径
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QDirIterator>
#include <QDebug>
#include <QStandardPaths>
void text_standardPaths()
{
	//获取标准路径 include <QStandardPaths>头文件
    for (size_t i = 0; i < 21; i++)
    {
        //循环21是因为QStandardPaths的枚举有20个,QStandardPaths::StandardLocation(i)这里是构造这个类型,不是强转
        qDebug()<< QStandardPaths::StandardLocation(i)<<"          "<< QStandardPaths::standardLocations(QStandardPaths::StandardLocation(i));
    }
    //返回一个用writableLocation
    qDebug() << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    text_standardPaths();

    return 0;//a.exec();
}

  • 运行结果
    在这里插入图片描述

QStorageInfo

  • 允许检索有关卷的空间、挂载点、标签和文件系统名称的信息。
#include <QApplication>
#include <QWidget>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QSettings>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDir>
#include <QDirIterator>
#include <QDebug>
#include <QStandardPaths>
#include <QStorageInfo>
void text_storageInfo()
{
    //头文件 #include <QStorageInfo>
    //return in Windows the volume where the operating system is installed.
    QStorageInfo storage = QStorageInfo::root();

    qDebug() << storage.rootPath();
    if (storage.isReadOnly())
        qDebug() << "isReadOnly:" << storage.isReadOnly();

    qDebug() << "name:" << storage.name();
    qDebug() << "fileSystemType:" << storage.fileSystemType();
    qDebug() << "size:" << storage.bytesTotal() / 1000 / 1000 << "MB";
    qDebug() << "availableSize:" << storage.bytesAvailable() / 1000 / 1000 << "MB";
}
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    a.setOrganizationName("xiaogua");
    text_storageInfo();

    return 0;//a.exec();
}

  • 运行结果
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值