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
类型的变量,其中存储了要添加到列表中的字符串。 -
所以这里也有改成这样,默认列表参数方式
-
- foreach 是 Qt 框架提供的一个宏,用于在容器(如 QList、QVector、QSet 等)中进行迭代。它是 Qt 为了方便开发者进行容器遍历而提供的一种语法。
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();
}
- 运行结果