学习目标: 文件操作
前置环境
运行环境: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)