[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