[C++]linux下實現ls()函數遍歷目錄


轉載請注明原創:http://www.cnblogs.com/StartoverX/p/4600794.html 

需求:在linux下遍歷目錄,輸出目錄中各文件名。

  在linux下遍歷目錄的相關函數有:

  #include <dirent.h>

  DIR* opendir(const char* dir_path);

  struct dirent* readdir(DIR* dirp);

  int closedir(DIR* dirp);

  int lstat(const chat* filename,struct stat* st);

在這里涉及到幾個結構體:DIR,struct dirent,struct stat:

  DIR結構體是一個內部結構,類似與FILE,用來保存當前被讀取的目錄的信息:

truct __dirstream { void     *__fd; char     *__data; int __entry_data; char     *__ptr; int __entry_ptr; size_t __allocation; size_t __size; __libc_lock_define (, __lock) }; typedef struct __dirstream DIR;

  struct dirent,指向文件夾下的目錄內容:

struct dirent { long d_ino; /* inode number 索引節點號 */ off_t d_off; /* offset to this dirent 在目錄文件中的偏移 */ unsigned short d_reclen; /* length of this d_name 文件名長 */ unsigned char d_type; /* the type of d_name 文件類型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最長256字符 */ }

  struct stat結構體保存文件信息,通過stat(),fstat(),lstat()函數返回,這三個函數的區別是:stat()傳入文件路徑得到stat,lstat()當傳入的是符號鏈文件時,得到的是符號鏈文件的信息而不是符號鏈指向的文件,fstat()傳入的是文件描述符而不是文件路徑。

struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for file system I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ };

  以下是ls()函數的全部實現,通過opendir()得到DIR*指針,readdir()函數獲得指向struct dirent結構的指針,再通過struct stat得到每一個文件的信息。按字母順序先輸出目錄文件名,再輸出普通文件。

int ls(std::string path,std::string& ret) { DIR* dirp = opendir(path.c_str()); if(!dirp) { return -1; } struct stat st; struct dirent *dir; std::vector<std::string> file_name; std::vector<std::string> dir_name; while((dir = readdir(dirp)) != NULL) { if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..") == 0) { continue; } std::string full_path = path + dir->d_name; if(lstat(full_path.c_str(),&st) == -1) { continue; } std::string name = dir->d_name; //replace the blank char in name with "%$".
        while(name.find(" ") != std::string::npos) { name.replace(name.find(" "),1,"$%"); } if(S_ISDIR(st.st_mode)) //S_ISDIR()宏判斷是否是目錄文件 { name += "[d]"; dir_name.push_back(name); } else { file_name.push_back(name); } } closedir(dirp); sort(file_name.begin(),file_name.end()); sort(dir_name.begin(),dir_name.end()); std::stringstream ss_ret; int count = 0; for(auto i=dir_name.begin();i!=dir_name.end();i++) { ss_ret<<*i; count++; if(count%5 == 0) { ss_ret<<std::endl; } else { ss_ret<<"  "; } } for(auto i=file_name.begin();i!=file_name.end();i++) { ss_ret<<*i; count++; if(count%5 == 0) //每五個名字回車。 { ss_ret<<std::endl; } else { ss_ret<<"  "; } } ret = ss_ret.str(); return 0; }

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM