關於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<file_count; 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");
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<dir_count; 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");
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<list.size());
}
分析:此方式采用遞歸的思路解決,也是網上大多數人用的辦法,個人建議摒棄!遞歸的效率真心不敢接受,而且代碼看起來也費勁。
總結:通過以上兩種方式比較,關於遍歷子孫文件夾的方式,采用“方式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);
更多關於獲取文件圖標、類型的詳細信息請查看:
http://blog.sina.com.cn/s/blog_a6fb6cc90101dx99.html