注意哦,這裡的全部文件是包括所有文件夾的子文件夾中的所有文件。
下面舉個例子詳細說明
我們要遍歷的文件夾是MSDN這個文件夾,但是MSDN這個文件夾有一些子文件夾,1033這個文件夾就是MSDN的孫子輩的文件夾,我們要做的是把這個MSDN目錄下的全部,當然也包括1033這個文件夾內的文件在內的所有都訪問到。
下面介紹一下QDir這個類的entryInfoList方法,QFileInfoListQDir::entryInfoList
這個函數的返回值是QFileInfoList類型的,
typedef QList<QFileInfo> QFileInfoList;
QT中封裝了很多這樣的List,比如QStringList實際上就是
typedef QList<QString> QStringList;
了解了這點之後就知道這個QFileInfoList實際上是個容器,裡面裝的都是QFileInfo類型的對象,QT助手中給出的解釋是這樣的Returns a list of QFileInfo objects for all the files and directories in the directory
這是一個裝QFileInfo類型的容器,而QFileInfo中封裝的是什麼呢?QFileInfo類提供的是與系統無關的文件信息,這裡就重點介紹結果和本文相關的幾個方法,
QString QFileInfo::fileName () const
這個方法會返回QString類型的文件名
例如:
QFileInfo fi("/tmp/archive.tar.gz"); QString name = fi.fileName(); // name = "archive.tar.gz"
發現QT的強大沒有,直接就把文件名獲取了。
bool QFileInfo::isDir () const
這個方如果對象指向一個目錄或者符號鏈接指向目錄則返回true,否則返回false。就是用來判斷是目錄還是其他東東的!
QString QFileInfo::filePath () const
返回文件名,包括路徑絕對或相對)。
下面需要介紹幾個QDir類的方法
bool QDir::exists () const
這是判斷以參數中為路徑是否存在,如果存在該路徑則返回真。
這個路徑是什麼路徑,應該在QDir初始化的時候給出,或者用這個
void QDir::setPath ( const QString & path )
下面的是設置過濾器和排序方式的函數
void QDir::setFilter ( Filters filters ) void QDir::setSorting ( SortFlags sort )
下面就是我們遞歸實現
void findFile(const QString & path) { QDir dir(path); if (!dir.exists()) return ; dir.setFilter(QDir::Dirs|QDir::Files); dir.setSorting(QDir::DirsFirst); QFileInfoList list = dir.entryInfoList(); QStringList infolist = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); int i = 0; do{ QFileInfo fileInfo = list.at(i); if(fileInfo.fileName()=="."|fileInfo.fileName()=="..") { i++; continue; } bool bisDir = fileInfo.isDir(); if(bisDir) { findFile(fileInfo.filePath()); } else { //這裡就是你想要對文件的操作了 for(int m = 0; m <infolist.size(); m++) { //這裡是獲取當前要處理的文件名 QString fileName = infolist.at(m); } break;//這裡一定要break退出while循環,因為infolist中的文件訪問完之後,當前文件夾下已經沒有任何文件了,這裡是遞歸的返回 } i++; }while(i < list.size());//這裡是list.size(),也就是當前文件夾下的文件夾數和文件數的和再+2 }
說明
這裡6,7行是設置保留文件和文件夾並按文件夾先序的順序排列。也就是list先放的是文件夾後方的是文件的信息QFileInfo,這裡的第8行list存當前目錄下所有文件夾和文件的信息,infolist存放所有的文件的文件名,很相似,但是infolist應該是我們可以處理的東西,而文件夾我們只能對其進行深度優先的訪問,就是不停的一層一層的打開文件夾,知道一個目錄裡沒有文件夾為止,然後返回上一層目錄繼續打開下面的文件夾;
這裡第10行的i是記錄當前訪問的是第幾個QFileInfo對象,所以while循環退出的條件是第36行寫的那樣;
這裡的第13行的判斷應該就是符號鏈接指向目錄這種東東吧;
這裡18-22行是進行深度優先訪問,只要是目錄就深入;
23-34行是對文件的處理,這裡是對每個目錄內的文件進行處理,infolist存的是當前目錄下的文件名列表,可以通過文件名訪問文件。主要的操作都可以放在這個for循環中來實現你的功能,之後要在else結束前break,如果不break會出現什麼問題呢?會造成文件的重復訪問,當你for循環結束的時候當前文件夾已經沒有文件了因為文件排放在文件夾的後面),而當前的i可能不是最後的文件或文件夾的下標,所以while循環會繼續,這樣就會繼續在執行若干次for循環,直到i==list.size(),這樣的操作對於文件數量比較小的文件夾開銷不是很大,但是當文件夾內的文件數量很大的時候會造成資源的浪費,相同的文件重復的操作也會造成一些錯誤,比如我們想要把這些文件都存放在一個vector中的時候就會產生很多相同的文件的情況,改變vector容器是不明智的選擇,因為即使換成set容器執行同樣存在,同樣會造成資源浪費。
網上這段短短的代碼不知道被人黏貼了多少次,但是沒人去分析這裡的問題
http://blog.csdn.net/bzhxuexi/article/details/10095651
這個就是一個典型的錯誤,所以大家在貼代碼前一定要自己先運行試試,不要誤人子弟啊!
本文出自 “賣萌程序員” 博客,請務必保留此出處http://7677869.blog.51cto.com/7667869/1281557