现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Qt编程:遍历文件夹

2014-12-19 21:31 工业·编程 ⁄ 共 4766字 ⁄ 字号 暂无评论

关于Qt操作文件夹、文件的知识用途较多,比如遍历下一层乃至所有子孙文件、文件夹,获取它们的一些信息(大小、类型、最后更改时间等)。当然,也可以进行级联删除。

首先看简单的:

一、Qt遍历文件夹下一层的文件

方式1:

void ImageTree::addFolderImages(QString path)

{

//判断路径是否存在

QDir dir(path);

if(!dir.exists())

{

return;

}

dir.setFilter(QDir::Files | QDir::NoSymLinks);

QFileInfoList list = dir.entryInfoList();

int file_count = list.count();

if(file_count <= 0)

{

return;

}

QStringList string_list;

for(int i=0; i

{

QFileInfo file_info = list.at(i);

QString suffix = file_info.suffix();

if(QString::compare(suffix, QString("png"), Qt::CaseInsensitive) == 0) 

QString absolute_file_path = file_info.absoluteFilePath();

string_list.append(absolute_file_path);

}

}

}

分析:遍历文件的下一层,对于系统而言包括:文件夹、文件、快捷方式,使用setFilter即可过滤。通过entryInfoList则可以获取过滤后所得到的文件夹下的文件信息列表,遍历文件通过操作QFileInfo可得到所需的文件详细信息(大小、类型、后缀等)。

方式2:

void ImageTree::addFolderImages(QString path)

{

//判断路径是否存在

QDir dir(path);

if(!dir.exists())

{

return;

}

QStringList filters;

filters<<QString("*.jpeg")<<QString("*.jpg")<<QString("*.png")<<QString("*.tiff")<<QString("*.gif")<<QString("*.bmp");

dir.setFilter(QDir::Files | QDir::NoSymLinks); //设置类型过滤器,只为文件格式

dir.setNameFilters(filters);  //设置文件名称过滤器,只为filters格式(后缀为.jpeg等图片格式)

int dir_count = dir.count();

if(dir_count <= 0)

{

return;

}

QStringList string_list;

//获取分隔符

//QChar separator = QDir::separator();

QChar separator = QChar('/');

if(!path.contains(separator))

{

separator = QChar('\\');

}

QChar last_char = path.at(path.length()-1);

if(last_char == separator)

{

separator = QChar();

}

for(uint i=0; i

{

QString file_name = dir[i];  //文件名称

QString file_path = path + separator + file_name;   //文件全路径

string_list.append(file_path);

}

//string_list 添加完成之后,就可以查看list中的文件路径了

}

分析:setNameFilters顾名思义,就是过滤文件名称的。如果只需要获取指定路径下的文件名,则可去掉“获取分隔符”部分代码(因为我是为了获取文件的全路径)。

思考:QDir::separator()这是用于获取分隔符的,调试过程中发现path的分隔符为'/',奇怪的是获取到的为'\\',刚好相反,所以我通过contains的方式获取分隔符的(无非'/'与'\\')。

讨论:如果设定filters后,那么存在一定的问题。熟用Windows的应该都知道,文件名是忽略大小写的(包括扩展名),那么若filters设定了“*.jpg”之后,则就不可添加扩展名为“.JPG”、“.Jpg”等大小写兼有的文件了。

既然有问题,就有解决问题的方式。

1、问题来源是由扩展名引起,那么去掉setNameFilters(filters);

2、上述已经获取文件全路径,那么QFileInfo file_info(file_path)获取文件信息的对象

3、通过file_info.suffix()或者completeSuffix()来判定文件的后缀、扩展名

4、获取之后比较时忽略大小写即可。如:QString::compare(suffix, QString("*.jpeg"), Qt::CaseInsensitive) == 0

总结:通过以上两种方式比较,关于遍历下一层的方式,采用“方式1”较好。

二、级联遍历文件夹及其子孙文件夹中的文件

方式1:

void ImageTree::addSubFolderImages(QString path)

{

//判断路径是否存在

QDir dir(path);

if(!dir.exists())

{

return;

}

//获取所选文件类型过滤器

QStringList filters;

filters<<QString("*.jpeg")<<QString("*.jpg")<<QString("*.png")<<QString("*.tiff")<<QString("*.gif")<<QString("*.bmp");

//定义迭代器并设置过滤器

QDirIterator dir_iterator(path,

filters,

QDir::Files | QDir::NoSymLinks,

QDirIterator::Subdirectories);

QStringList string_list;

while(dir_iterator.hasNext())

{

dir_iterator.next();

QFileInfo file_info = dir_iterator.fileInfo();

QString absolute_file_path = file_info.absoluteFilePath();

string_list.append(file_path);

}

}

分析:QDirIterator定义过程中可设置过滤器,包括:文件名称、文件类型等。dir_iterator.next()这句话很重要,如果缺少将会进入死循环!

方式2:

QStringList string_list;

void ImageTree::addSubFolderImages(QString path)

{

QDir dir(path);

if(!dir.exists())

{

return;

}

dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks);

dir.setSorting(QDir::DirsFirst);

QFileInfoList list = dir.entryInfoList();

int i = 0;

bool is_dir;

do

{

QFileInfo file_info = list.at(i);

if(file_info.fileName() == "." | file_info.fileName() == "..")

{

i++;

continue;

}

is_dir = file_info.isDir();

if(is_dir)

{

//进行递归

addSubFolderImages(file_info.filePath());

}

else

{

//获取文件后缀并获取所选包含类型,若存在包含类型且后缀相同,则添加

QString suffix =  file_info.suffix();

if(QString::compare(suffix, QString("png"), Qt::CaseInsensitive) == 0) 

QString absolute_file_path = file_info.absoluteFilePath();

string_list.append(absolute_file_path);

}

}

i++;

}

while(i

}

分析:此方式采用递归的思路解决,也是网上大多数人用的办法,个人建议摒弃!递归的效率真心不敢接受,而且代码看起来也费劲。

总结:通过以上两种方式比较,关于遍历子孙文件夹的方式,采用“方式1”较好。

关于QFileInfo获取文件信息的方法可以查看API

方法如下:

void setFile(const QString &file);

void setFile(const QFile &file);

void setFile(const QDir &dir, const QString &file);

bool exists() const;

void refresh();

QString filePath() const;

QString absoluteFilePath() const;

QString canonicalFilePath() const;

QString fileName() const;

QString baseName() const;

QString completeBaseName() const;

QString suffix() const;

QString bundleName() const;

QString completeSuffix() const;

QString path() const;

QString absolutePath() const;

QString canonicalPath() const;

QDir dir() const;

QDir absoluteDir() const;

bool isReadable() const;

bool isWritable() const;

bool isExecutable() const;

bool isHidden() const;

bool isNativePath() const;

bool isRelative() const;

inline bool isAbsolute() const { return !isRelative(); }

bool makeAbsolute();

bool isFile() const;

bool isDir() const;

bool isSymLink() const;

bool isRoot() const;

bool isBundle() const;

QString readLink() const;

inline QString symLinkTarget() const { return readLink(); }

QString owner() const;

uint ownerId() const;

QString group() const;

uint groupId() const;

bool permission(QFile::Permissions permissions) const;

QFile::Permissions permissions() const;

qint64 size() const;

QDateTime created() const;

QDateTime lastModified() const;

QDateTime lastRead() const;

bool caching() const;

void setCaching(bool on);

给我留言

留言无头像?