這三個類相互有關聯,但是有不盡相同,首先從名字上看,QDir 和 QDirIterator 是針對於文件目錄的,也就是文件夾,我們知道,對於一個文件夾,可以包含很多文件,也可以包含其他文件夾,通常是一個樹的結構。文件夾里還可以包含符號鏈接,符號鏈接是指向其他文件或文件夾的一種鏈接,和Windows系統中的快捷方式有些類似,具體可參考這里。而QFileInfo主要是針對某一個具體的文件,來保存和這個文件相關的所有信息,比如文件名,路徑啥的。下面來看一個例子,是通過遞歸方法來查詢所有.mp3文件:
void recurseAddDir(QDir d, bool recursive=true, bool symlinks=false ) { d.setSorting( QDir::Name ); QDir::Filters df = QDir::Files | QDir::NoDotAndDotDot; if (recursive) df |= QDir::Dirs; if (not symlinks) df |= QDir::NoSymLinks; QStringList qsl = d.entryList(df, QDir::Name | QDir::DirsFirst); foreach (const QString &entry, qsl) { QFileInfo finfo(d, entry); if ( finfo.isDir() ) { QDir sd(finfo.absoluteFilePath()); recurseAddDir(sd); } else { if (finfo.completeSuffix()=="mp3") addMp3File(finfo.absoluteFilePath()); } } }
上面那個例子在遞歸函數recurseAddDir()中調用了功能函數addMp3File(),嚴重的限制了該函數的可重用性,下面來看用Iterator Pattern來實現的版本:
int main (int argc, char* argv[]) { QCoreApplication app(argc, argv); QDir dir = QDir::current(); if (app.arguments().size() > 1) { dir = app.arguments()[1]; } if (!dir.exists()) { cerr << dir.path() << " does not exist!" << endl; usage(); return -1; } QDirIterator qdi(dir.absolutePath(), QStringList() << "*.mp3", QDir::NoSymLinks | QDir::Files, QDirIterator::Subdirectories ); while (qdi.hasNext()) { addMp3File(qdi.next()); } }
這樣設計的好處是提高了代碼可重用性,而且更簡單了,這就是Design Pattern的魅力所在。